first commit

This commit is contained in:
168492376 2024-11-10 14:55:21 +08:00
commit 2578439e5f
22 changed files with 3831 additions and 0 deletions

16
CMakeLists.txt Normal file
View File

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 2.8)
add_library(libspp
src/readobsnav.c
src/const.c
src/init_val.c
src/decodeobs.c
src/str.c
src/obscode.c
src/decodenav.c
src/timeconvert.c
src/satellite.c
)
add_executable(main src/main.c)
target_link_libraries(main libspp m)

173
src/comtyp.h Normal file
View File

@ -0,0 +1,173 @@
#ifndef COMTYP_H
#define COMTYP_H
#include "const.h"
typedef struct
{
long long time; // time (s) expressed by standard time_t
double sec; // fraction of second under 1 s
}gtime_t;
typedef struct
{
int sys; // navigation system
int vs; // valid satellite flag single
double azel[2]; // azimuth/elevation angles {az,el} (rad)
double resp[NFREQ]; // residuals of pseudorange (m)
double resc[NFREQ]; // residuals of carrier-phase (m)
double icbias[NFREQ]; // glonass IC bias (cycles)
int vsat[NFREQ]; // valid satellite flag
int snr[NFREQ]; // signal strength (0.25 dBHz)
int lock[NFREQ]; // lock counter of phase
}ssat_t;
typedef struct
{
gtime_t time; // receiver sampling time (GPST)
int sat,rcv; // satellite/receiver number
int SNR[NFREQ+NEXOBS]; // signal strength (0.25 dBHz)
int LLI[NFREQ+NEXOBS]; // loss of lock indicator
int code[NFREQ+NEXOBS]; // code indicator (CODE_???)
int qualL[NFREQ+NEXOBS]; // quality of carrier phase measurement
int qualP[NFREQ+NEXOBS]; // quality of pseudorange measurement
double L[NFREQ+NEXOBS]; // observation data carrier-phase (cycle)
double P[NFREQ+NEXOBS]; // observation data pseudorange (m)
double D[NFREQ+NEXOBS]; // observation data doppler frequency (Hz)
}obsd_t;
typedef struct
{
int n,nmax; // number of obervation data/allocated
double tint; // time interval
obsd_t* data; // observation data records
}obs_t;
typedef struct
{
int sat; // satellite number
int iode,iodc; // IODE,IODC
int sva; // SV accuracy (URA index)
int svh; // SV health (0:ok)
int week; // GPS/QZS: gps week, GAL: galileo week
int code; // GPS/QZS: code on L2, GAL/CMP: data sources
int flag; // GPS/QZS: L2 P data flag, CMP: nav type
gtime_t toe,toc,ttr; // Toe,Toc,T_trans
// SV orbit parameters
double A,e,i0,OMG0,omg,M0,deln,OMGd,idot;
double crc,crs,cuc,cus,cic,cis;
double toes; // Toe (s) in week
double fit; // fit interval (h)
double f0,f1,f2; // SV clock parameters (af0,af1,af2)
double tgd[4]; // group delay parameters
// GPS/QZS:tgd(0)=TGD
// GAL :tgd(0)=BGD E5a/E1,tgd(1)=BGD E5b/E1
// CMP :tgd(0)=BGD1,tgd(1)=BGD2
double Adot,ndot; // Adot,ndot for CNAV
}eph_t;
typedef struct
{
int sat; // satellite number
int iode; // IODE (0-6 bit of tb field)
int frq; // satellite frequency number
int svh,sva,age; // satellite health, accuracy, age of operation
gtime_t toe; // epoch of epherides (gpst)
gtime_t tof; // message frame time (gpst)
double pos[3]; // satellite position (ecef) (m)
double vel[3]; // satellite velocity (ecef) (m/s)
double acc[3]; // satellite acceleration (ecef) (m/s^2)
double taun,gamn; // SV clock bias (s)/relative freq bias
double dtaun; // delay between L1 and L2 (s)
}geph_t;
typedef struct
{ /* SBAS ephemeris type */
int sat; /* satellite number */
gtime_t t0; /* reference epoch time (GPST) */
gtime_t tof; /* time of message frame (GPST) */
int sva; /* SV accuracy (URA index) */
int svh; /* SV health (0:ok) */
double pos[3]; /* satellite position (m) (ecef) */
double vel[3]; /* satellite velocity (m/s) (ecef) */
double acc[3]; /* satellite acceleration (m/s^2) (ecef) */
double af0, af1; /* satellite clock-offset/drift (s,s/s) */
}seph_t;
typedef struct
{
int sat; // satellite number
int svh; // sv health (0:ok)
int svconf; // as and sv config
int week; // GPS/QZS: gps week, GAL: galileo week
gtime_t toa; // Toa
// SV orbit parameters
double A,e,i0,OMG0,omg,M0,OMGd;
double toas; // Toa (s) in week
double f0,f1; // SV clock parameters (af0,af1)
}alm_t;
typedef struct
{
int n,nmax; // number of broadcast ephemeris
int ng,ngmax; // number of glonass ephemeris
int ns,nsmax; // number of sbas ephemeris
int ne,nemax; // number of precise ephemeris
int nc,ncmax; // number of precise clock
int na,namax; // number of almanac data
int nt,ntmax; // number of tec grid data
int nf,nfmax; // number of satellite fcb data
eph_t* eph; // GPS/QZS/GAL ephemeris
geph_t* geph; // GLONASS ephemeris
seph_t *seph; /* SBAS ephemeris */
alm_t* alm; // almanac data
double utc_gps[4]; // GPS delta-UTC parameters {A0,A1,T,W}
double utc_glo[4]; // GLONASS UTC GPS time parameters
double utc_gal[4]; // Galileo UTC GPS time parameters
double utc_qzs[4]; // QZS UTC GPS time parameters
double utc_cmp[4]; // BeiDou UTC parameters
double utc_irn[4]; // IRNSS UTC parameters
double utc_sbs[4]; // SBAS UTC parameters
double ion_gps[8]; // GPS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3}
double ion_gal[4]; // Galileo iono model parameters {ai0,ai1,ai2,0}
double ion_qzs[8]; // QZSS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3}
double ion_cmp[8]; // BeiDou iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3}
double ion_irn[8]; // IRNSS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3}
int leaps; // leap seconds (s)
double lam[MAXSAT][NFREQ];// carrier wave lengths (m)
double cbias[MAXSAT][3]; // satellite dcb (0:p1-p2,1:p1-c1,2:p2-c2) (m)
double rbias[MAXRCV][2][3];// receiver dcb (0:p1-p2,1:p1-c1,2:p2-c2) (m)
double wlbias[MAXSAT]; // wide-lane bias (cycle)
double glo_cpbias[4]; // glonass code-phase bias {1C,1P,2C,2P} (m)
char glo_fcn[MAXPRNGLO+1];// glonass frequency channel number + 8
}nav_t;
typedef struct
{
char name[MAXANT]; // marker name
char marker[MAXANT]; // marker number
char antdes[MAXANT]; // antenna descriptor
char antsno[MAXANT]; // antenna serial number
char rectype[MAXANT]; // receiver type descriptor
char recver[MAXANT]; // receiver firmware version
char recsno[MAXANT]; // receiver serial number
int antsetup; // antenna setup id
int itrf; // ITRF realization year
int deltype; // antenna delta type (0:enu,1:xyz)
double pos[3]; // station position (ecef) (m)
double del[3]; // antenna position delta (e/n/u or x/y/z) (m)
double hgt; // antenna height (m)
}sta_t;
typedef struct
{
int n; //number of index
int frqIdx[MAXOBSTYPE]; //signal frequency (1:L1,2:L2,...)
int pos[MAXOBSTYPE]; //signal index in obs data (-1:no)
int pri[MAXOBSTYPE]; //signal priority (15-0)
int type[MAXOBSTYPE]; //type (0:C,1:L,2:D,3:S)
int code[MAXOBSTYPE]; //obs code (CODE_L??)
double shift[MAXOBSTYPE];//phase shift (cycle)
}sigind_t;
#endif

208
src/const.c Normal file
View File

@ -0,0 +1,208 @@
#include "const.h"
// Definition of constant ----------------------------------------------------
const double PI = 3.1415926535897932e0; //! pi
const double D2R = (PI/180.e0); //! deg to rad
const double R2D = (180.e0/PI); //! rad to deg
const double CLIGHT = 299792458.e0; //! speed of light (m/s)
const double SC2RAD = 3.1415926535898e0; //! semi-circle to radian (IS-GPS)
const double AU = 149597870691.e0; //! 1 AU (m)
const double AS2R = (D2R/3600.e0); //! arc sec to radian
const double OMGE = 7.2921151467e-5; //! earth angular velocity (IS-GPS) (rad/s)
const double RE_WGS84 = 6378137.e0; //! earth semimajor axis (WGS84) (m)
const double FE_WGS84 = (1.e0/298.257223563e0); //! earth flattening (WGS84)
const double HION = 350000.e0; //! ionosphere height (m)
const double FREQL1 = 1.57542e9; //! L1/E1 frequency (Hz)
const double FREQL2 = 1.22760e9; //! L2 frequency (Hz)
const double FREQL5 = 1.17645e9; //! L5/E5a frequency (Hz)
const double FREQL6 = 1.27875e9; //! E6/LEX frequency (Hz)
const double FREQE5b = 1.20714e9; //! E5b frequency (Hz)
const double FREQE5ab = 1.191795e9; //! E5a+b frequency (Hz)
const double FREQs = 2.492028e9; //! S frequency (Hz)
const double FREQ1_GLO = 1.60200e9; //! GLONASS G1 base frequency (Hz)
const double DFRQ1_GLO = 0.56250e6; //! GLONASS G1 bias frequency (Hz/n)
const double FREQ2_GLO = 1.24600e9; //! GLONASS G2 base frequency (Hz)
const double DFRQ2_GLO = 0.43750e6; //! GLONASS G2 bias frequency (Hz/n)
const double FREQ1a_GLO = 1.600995E9; // GLONASS G1a frequency (Hz)
const double FREQ2a_GLO = 1.248060E9; // GLONASS G2a frequency (Hz)
const double FREQ3_GLO = 1.202025e9; //! GLONASS G3 frequency (Hz)
const double FREQ1_CMP = 1.561098e9; //! BeiDou B1 frequency (Hz)
const double FREQ2_CMP = 1.20714e9; //! BeiDou B2 frequency (Hz)
const double FREQ3_CMP = 1.26852e9; //! BeiDou B3 frequency (Hz)
const double EFACT_GPS = 1.e0; //! error factor: GPS
const double EFACT_GLO = 1.5e0; //! error factor: GLONASS
const double EFACT_GAL = 1.e0; //! error factor: Galileo
const double EFACT_QZS = 1.e0; //! error factor: QZSS
const double EFACT_CMP = 1.e0; //! error factor: BeiDou
const double EFACT_IRN = 1.5e0; //! error factor: IRNSS
const double EFACT_SBS = 3.e0; //! error factor: SBAS
const double DTTOL = 0.015e0; //! tolerance of time difference (s)
const double MAXDTOE = 7200.e0; //! max time difference to GPS Toe (s)
const double MAXDTOE_QZS = 7200.e0; //! max time difference to QZSS Toe (s)
const double MAXDTOE_GAL = 14400.e0; //! max time difference to Galileo Toe (s)
const double MAXDTOE_CMP = 21600.e0; //! max time difference to BeiDou Toe (s)
const double MAXDTOE_GLO = 1800.e0; //! max time difference to GLONASS Toe (s)
const double MAXDTOE_SBS = 360.e0; //! max time difference to SBAS Toe (s)
const double MAXDTOE_S = 86400.e0; //! max time difference to ephem toe (s) for other
const double MAXGDOP = 300.e0; //! max GDOP
const double INT_SWAP_TRAC = 86400.e0; //! swap interval of trace file (s)
const double INT_SWAP_STAT = 86400.e0; //! swap interval of solution status file (s)
const double MAXSBSAGEF = 30.e0; //! max age of SBAS fast correction (s)
const double MAXSBSAGEL = 1800.e0; //! max age of SBAS long term corr (s)
const double RNX2VER = 2.10e0; //! RINEX ver.2 default output version
const double RNX3VER = 3.00e0; //! RINEX ver.3 default output version
const char COMMENTH[2] = "%"; //! comment line indicator for solution
const char MSG_DISCONN[13] = "$_DISCONNECT"; //! disconnect message
const double P2_5 = 0.03125e0; //! 2^-5
const double P2_6 = 0.015625e0; //! 2^-6
const double P2_11 = 4.882812500000000e-04; //! 2^-11
const double P2_15 = 3.051757812500000e-05; //! 2^-15
const double P2_17 = 7.629394531250000e-06; //! 2^-17
const double P2_19 = 1.907348632812500e-06; //! 2^-19
const double P2_20 = 9.536743164062500e-07; //! 2^-20
const double P2_21 = 4.768371582031250e-07; //! 2^-21
const double P2_23 = 1.192092895507810e-07; //! 2^-23
const double P2_24 = 5.960464477539063e-08; //! 2^-24
const double P2_27 = 7.450580596923828e-09; //! 2^-27
const double P2_29 = 1.862645149230957e-09; //! 2^-29
const double P2_30 = 9.313225746154785e-10; //! 2^-30
const double P2_31 = 4.656612873077393e-10; //! 2^-31
const double P2_32 = 2.328306436538696e-10; //! 2^-32
const double P2_33 = 1.164153218269348e-10; //! 2^-33
const double P2_35 = 2.910383045673370e-11; //! 2^-35
const double P2_38 = 3.637978807091710e-12; //! 2^-38
const double P2_39 = 1.818989403545856e-12; //! 2^-39
const double P2_40 = 9.094947017729280e-13; //! 2^-40
const double P2_43 = 1.136868377216160e-13; //! 2^-43
const double P2_48 = 3.552713678800501e-15; //! 2^-48
const double P2_50 = 8.881784197001252e-16; //! 2^-50
const double P2_55 = 2.775557561562891e-17; //! 2^-55
//! rtkcmn.f90 ----------------------------------------------------------------
const double MAX_VAR_EPH = 9e4; //! max variance eph to reject satellite (m^2)
const double gpst0[6]={1980,1, 6,0,0,0}; //! gps time reference
const double gst0[6] ={1999,8,22,0,0,0}; //! galileo system time reference
const double bdt0[6] ={2006,1, 1,0,0,0}; //! beidou time reference
const double lam_carr[MAXFREQ]={ //! carrier wave length (m)
CLIGHT/FREQL1,CLIGHT/FREQL2,CLIGHT/FREQL5,CLIGHT/FREQL6,CLIGHT/FREQE5b,
CLIGHT/FREQE5ab,CLIGHT/FREQs};
//! leap seconds (y,m,d,h,m,s,utc-gpst)
const double leaps[19][7]={
{2017,1,1,0,0,0,-18},
{2015,7,1,0,0,0,-17},
{2012,7,1,0,0,0,-16},
{2009,1,1,0,0,0,-15},
{2006,1,1,0,0,0,-14},
{1999,1,1,0,0,0,-13},
{1997,7,1,0,0,0,-12},
{1996,1,1,0,0,0,-11},
{1994,7,1,0,0,0,-10},
{1993,7,1,0,0,0, -9},
{1992,7,1,0,0,0, -8},
{1991,1,1,0,0,0, -7},
{1990,1,1,0,0,0, -6},
{1988,1,1,0,0,0, -5},
{1985,7,1,0,0,0, -4},
{1983,7,1,0,0,0, -3},
{1982,7,1,0,0,0, -2},
{1981,7,1,0,0,0, -1},
{0 ,0,0,0,0,0, 0}
};
//! observation code strings
const char obscodes[60][3]={
{" "},{"1C"},{"1P"},{"1W"},{"1Y"}, {"1M"},{"1N"},{"1S"},{"1L"},{"1E"}, //! 0- 9
{"1A"},{"1B"},{"1X"},{"1Z"},{"2C"}, {"2D"},{"2S"},{"2L"},{"2X"},{"2P"}, //! 10-19
{"2W"},{"2Y"},{"2M"},{"2N"},{"5I"}, {"5Q"},{"5X"},{"7I"},{"7Q"},{"7X"}, //! 20-29
{"6A"},{"6B"},{"6C"},{"6X"},{"6Z"}, {"6S"},{"6L"},{"8L"},{"8Q"},{"8X"}, //! 30-39
{"2I"},{"2Q"},{"6I"},{"6Q"},{"3I"}, {"3Q"},{"3X"},{"1I"},{"1Q"},{"5A"}, //! 40-49
{"5B"},{"5C"},{"9A"},{"9B"},{"9C"}, {"9X"},{" "},{" "},{" "},{" "} //! 50-59
};
//! 1:L1/E1, 2:L2/B1, 3:L5/E5a/L3, 4:L6/LEX/B3, 5:E5b/B2, 6:E5(a+b), 7:S
const int obsfreqs[60]={
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, //! 0- 9
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, //! 10-19
2, 2, 2, 2, 3, 3, 3, 5, 5, 5, //! 20-29
4, 4, 4, 4, 4, 4, 4, 6, 6, 6, //! 30-39
2, 2, 4, 4, 3, 3, 3, 1, 1, 3, //! 40-49
3, 3, 7, 7, 7, 7, 0, 0, 0, 0 //! 50-59
};
//! code priority table
//! L1/E1; L2/B1; L5/E5a/L3; L6/LEX/B3; E5b/B2; E5(a+b); S
const char codepris[7][MAXFREQ][17]={
{"CPYWMNSL ","PYWCMNDSLX","IQX "," "," "," "," "}, //! GPS
{"PC ","PC ","IQX "," "," "," "," "}, //! GLO
{"CABXZ "," ","IQX ","ABCXZ ","IQX ","IQX "," "}, //! GAL
{"CSLXZ ","SLX ","IQX ","SLX "," "," "," "}, //! QZS
{"C "," ","IQX "," "," "," "," "}, //! SBS
{"IQX ","IQX ","IQX ","IQX ","IQX "," "," "}, //! BDS
{" "," ","ABCX "," "," "," ","ABCX "} //! IRN
};
//! ephemeris.f90 -------------------------------------------------------------
const double RE_GLO = 6378136.e0; //! radius of earth (m) ref (2)
const double MU_GPS = 3.9860050e14; //! gravitational constant ref (1)
const double MU_GLO = 3.9860044e14; //! gravitational constant ref (2)
const double MU_GAL = 3.986004418e14; //! earth gravitational constant ref (7)
const double MU_CMP = 3.986004418e14; //! earth gravitational constant ref (9)
const double J2_GLO = 1.0826257e-3; //! 2nd zonal harmonic of geopot ref (2)
const double OMGE_GLO = 7.292115e-5; //! earth angular velocity (rad/s) ref (2)
const double OMGE_GAL = 7.2921151467e-5; //! earth angular velocity (rad/s) ref (7)
const double OMGE_CMP = 7.292115e-5; //! earth angular velocity (rad/s) ref (9)
const double SIN_5 = -0.0871557427476582e0; //! dsin(-5.e0 deg)
const double COS_5 = 0.9961946980917456e0; //! dcos(-5.e0 deg)
const double ERREPH_GLO = 5.e0; //! error of glonass ephemeris (m)
const double TSTEP = 60.e0; //! integration step glonass ephemeris (s)
const double RTOL_KEPLER = 1e-13; //! relative tolerance for Kepler equation
const double DEFURASSR = 0.15e0; //! default accurary of ssr corr (m)
const double MAXECORSSR = 10.e0; //! max orbit correction of ssr (m)
const double MAXCCORSSR = (1e-6*CLIGHT); //! max clock correction of ssr (m)
const double MAXAGESSR = 90.e0; //! max age of ssr orbit and clock (s)
const double MAXAGESSR_HRCLK = 10.e0; //! max age of ssr high-rate clock (s)
const double STD_BRDCCLK = 30.e0; //! error of broadcast clock (m)
const double STD_GAL_NAPA = 500.e0; //! error of galileo ephemeris for NAPA (m)
const int eph_sel[6]={0,0,1,0,0,0}; //! GPS,GLO,GAL,QZS,BDS,SBS (ephemeris selections)
//! pntpos.f90 ----------------------------------------------------------------
const double ERR_ION = 5.e0 ; //! ionospheric delay std (m)
const double ERR_TROP = 3.e0; //! tropspheric delay std (m)
const double ERR_SAAS = 0.3e0; //! saastamoinen model error std (m)
const double ERR_BRDCI = 0.5e0; //! broadcast iono model error factor
const double ERR_CBIAS = 0.3e0; //! code bias error std (m)
const double REL_HUMI = 0.7e0; //! relative humidity for saastamoinen model
//! rinex.f90 -----------------------------------------------------------------
const char systyps[8] = "GREJSCI"; //! satellite system codes
const char obstyps[5] = "CLDS"; //! obs type codes
const char frqtyps[8] = "1256789"; //! frequency codes
const double ura_eph[16] = { //! ura values (ref [3] 20.3.3.3.1.1)
2.4,3.4,4.85,6.85,9.65,13.65,24.0,48.0,96.0,
192.0,384.0,768.0,1536.0,3072.0,6144.0,0.00};
const double ura_nominal[16] = { //! ura nominal values
2.0,2.8,4.0,5.7,8.0,11.3,16.0,32.0,64.0,
128.0,256.0,512.0,1024.0,2048.0,4096.0,8192.0};

504
src/const.h Normal file
View File

@ -0,0 +1,504 @@
#ifndef CONST_H
#define CONST_H
#define SNR_UNIT 0.25 /* SNR unit (dBHz) */
#define MAXFREQ 7 //! max NFREQ
#define SYS_NONE 0 //!0x00 //! navigation system: none
#define SYS_GPS 1 //!0x01 //! navigation system: GPS
#define SYS_SBS 2 //!0x02 //! navigation system: SBAS
#define SYS_GLO 4 //!0x04 //! navigation system: GLONASS
#define SYS_GAL 8 //!0x08 //! navigation system: Galileo
#define SYS_QZS 16 //!0x10 //! navigation system: QZSS
#define SYS_CMP 32 //!0x20 //! navigation system: BeiDou
#define SYS_IRN 64 //!0x40 //! navigation system: IRNS
#define SYS_LEO 128 //!0x80 //! navigation system: LEO
#define SYS_ALL 255 //!0xFF //! navigation system: all
#define TSYS_GPS 0 //! time system: GPS time
#define TSYS_UTC 1 //! time system: UTC
#define TSYS_GLO 2 //! time system: GLONASS time
#define TSYS_GAL 3 //! time system: Galileo time
#define TSYS_QZS 4 //! time system: QZSS time
#define TSYS_CMP 5 //! time system: BeiDou time
#define TSYS_IRN 6 //! time system: IRNSS time
#define NFREQ 3 //! number of carrier frequencies
#define NFREQGLO 2 //! number of carrier frequencies of GLONASS
#define NEXOBS 3 //! number of extended obs codes
#define MINPRNGPS 1 //! min satellite PRN number of GPS
#define MAXPRNGPS 32 //! max satellite PRN number of GPS
#define NSATGPS (MAXPRNGPS-MINPRNGPS+1) //! number of GPS satellites
#define NSYSGPS 1
#define MINPRNGLO 1 //! min satellite slot number of GLONASS
#define MAXPRNGLO 27 //! max satellite slot number of GLONASS
#define NSATGLO (MAXPRNGLO-MINPRNGLO+1) //! number of GLONASS satellites
#define NSYSGLO 1
#define MINPRNGAL 1 //! min satellite PRN number of Galileo
#define MAXPRNGAL 36 //! max satellite PRN number of Galileo
#define NSATGAL (MAXPRNGAL-MINPRNGAL+1) //! number of Galileo satellites
#define NSYSGAL 1
#define MINPRNQZS 193 //! min satellite PRN number of QZSS
#define MAXPRNQZS 202 //! max satellite PRN number of QZSS
#define MINPRNQZS_S 183 //! min satellite PRN number of QZSS SAIF
#define MAXPRNQZS_S 191 //! max satellite PRN number of QZSS SAIF
#define NSATQZS (MAXPRNQZS-MINPRNQZS+1) //! number of QZSS satellites
#define NSYSQZS 1
#define MINPRNCMP 1 //! min satellite sat number of BeiDou
#define MAXPRNCMP 37 //! max satellite sat number of BeiDou
#define NSATCMP (MAXPRNCMP-MINPRNCMP+1) //! number of BeiDou satellites
#define NSYSCMP 1
#define MINPRNIRN 1 //! min satellite sat number of IRNSS
#define MAXPRNIRN 7 //! max satellite sat number of IRNSS
#define NSATIRN (MAXPRNIRN-MINPRNIRN+1) //! number of IRNSS satellites
#define NSYSIRN 1
#define MINPRNLEO 1 //! min satellite sat number of LEO
#define MAXPRNLEO 10 //! max satellite sat number of LEO
#define NSATLEO (MAXPRNLEO-MINPRNLEO+1) //! number of LEO satellites
#define NSYSLEO 1
#define NSYS (NSYSGPS+NSYSGLO+NSYSGAL+NSYSQZS+NSYSCMP+NSYSIRN+NSYSLEO) //! number of systems
#define MINPRNSBS 120 //! min satellite PRN number of SBAS
#define MAXPRNSBS 142 //! max satellite PRN number of SBAS
#define NSATSBS (MAXPRNSBS-MINPRNSBS+1) //! number of SBAS satellites
#define MAXSAT (NSATGPS+NSATGLO+NSATGAL+NSATQZS+NSATCMP+NSATIRN+NSATSBS+NSATLEO)
//! max satellite number (1 to MAXSAT)
#define MAXSTA 255
#define MAXOBS 128 //! max number of obs in an epoch
#define MAXRCV 64 //! max receiver number (1 to MAXRCV)
#define MAXOBSTYPE 64 //! max number of obs type in RINEX
#define MAXEXFILE 1024 //! max number of expanded files
#define MAXSBSURA 8 //! max URA of SBAS satellite
#define MAXBAND 10 //! max SBAS band of IGP
#define MAXNIGP 201 //! max number of IGP in SBAS band
#define MAXNGEO 4 //! max number of GEO satellites
#define MAXCOMMENT 10 //! max number of RINEX comments
#define MAXSTRPATH 1024 //! max length of stream path
#define MAXSTRMSG 1024 //! max length of stream message
#define MAXSTRRTK 8 //! max number of stream in RTK server
#define MAXSBSMSG 32 //! max number of SBAS msg in RTK server
#define MAXSOLMSG 8191 //! max length of solution message
#define MAXRAWLEN 4096 //! max length of receiver raw message
#define MAXERRMSG 4096 //! max length of error/warning message
#define MAXANT 64 //! max length of station name/antenna type
#define MAXSOLBUF 256 //! max number of solution buffer
#define MAXSOLNUM 86400 //! max number of solution in program
#define MAXOBSBUF 128 //! max number of observation data buffer
#define MAXNRPOS 16 //! max number of reference positions
#define MAXLEAPS 64 //! max number of leap seconds table
#define MAXGISLAYER 32 //! max number of GIS data layers
#define MAXRCVCMD 4096 //! max length of receiver commands
#define OBSTYPE_PR 1 //!#01 //! observation type: pseudorange
#define OBSTYPE_CP 2 //!#02 //! observation type: carrier-phase
#define OBSTYPE_DOP 4 //!#04 //! observation type: doppler-freq
#define OBSTYPE_SNR 8 //!#08 //! observation type: SNR
#define OBSTYPE_ALL 255 //!#FF //! observation type: all
#define FREQTYPE_L1 1 //!0x01 //! frequency type: L1/E1
#define FREQTYPE_L2 2 //!0x02 //! frequency type: L2/B1
#define FREQTYPE_L5 4 //!0x04 //! frequency type: L5/E5a/L3
#define FREQTYPE_L6 8 //!0x08 //! frequency type: E6/LEX/B3
#define FREQTYPE_L7 16 //!0x10 //! frequency type: E5b/B2
#define FREQTYPE_L8 32 //!0x20 //! frequency type: E5(a+b)
#define FREQTYPE_L9 64 //!0x40 //! frequency type: S
#define FREQTYPE_ALL 255 //!0xFF //! frequency type: all
#define CODE_NONE 0 //! obs code: none or unknown
#define CODE_L1C 1 //! obs code: L1C/A,G1C/A,E1C (GPS,GLO,GAL,QZS,SBS)
#define CODE_L1P 2 //! obs code: L1P,G1P (GPS,GLO)
#define CODE_L1W 3 //! obs code: L1 Z-track (GPS)
#define CODE_L1Y 4 //! obs code: L1Y (GPS)
#define CODE_L1M 5 //! obs code: L1M (GPS)
#define CODE_L1N 6 //! obs code: L1codeless (GPS)
#define CODE_L1S 7 //! obs code: L1C(D) (GPS,QZS)
#define CODE_L1L 8 //! obs code: L1C(P) (GPS,QZS)
#define CODE_L1E 9 //! (not used)
#define CODE_L1A 10 //! obs code: E1A (GAL)
#define CODE_L1B 11 //! obs code: E1B (GAL)
#define CODE_L1X 12 //! obs code: E1B+C,L1C(D+P) (GAL,QZS)
#define CODE_L1Z 13 //! obs code: E1A+B+C,L1SAIF (GAL,QZS)
#define CODE_L2C 14 //! obs code: L2C/A,G1C/A (GPS,GLO)
#define CODE_L2D 15 //! obs code: L2 L1C/A-(P2-P1) (GPS)
#define CODE_L2S 16 //! obs code: L2C(M) (GPS,QZS)
#define CODE_L2L 17 //! obs code: L2C(L) (GPS,QZS)
#define CODE_L2X 18 //! obs code: L2C(M+L),B1I+Q (GPS,QZS,CMP)
#define CODE_L2P 19 //! obs code: L2P,G2P (GPS,GLO)
#define CODE_L2W 20 //! obs code: L2 Z-track (GPS)
#define CODE_L2Y 21 //! obs code: L2Y (GPS)
#define CODE_L2M 22 //! obs code: L2M (GPS)
#define CODE_L2N 23 //! obs code: L2codeless (GPS)
#define CODE_L5I 24 //! obs code: L5/E5aI (GPS,GAL,QZS,SBS)
#define CODE_L5Q 25 //! obs code: L5/E5aQ (GPS,GAL,QZS,SBS)
#define CODE_L5X 26 //! obs code: L5/E5aI+Q/L5B+C (GPS,GAL,QZS,IRN,SBS)
#define CODE_L7I 27 //! obs code: E5bI,B2I (GAL,CMP)
#define CODE_L7Q 28 //! obs code: E5bQ,B2Q (GAL,CMP)
#define CODE_L7X 29 //! obs code: E5bI+Q,B2I+Q (GAL,CMP)
#define CODE_L6A 30 //! obs code: E6A (GAL)
#define CODE_L6B 31 //! obs code: E6B (GAL)
#define CODE_L6C 32 //! obs code: E6C (GAL)
#define CODE_L6X 33 //! obs code: E6B+C,LEXS+L,B3I+Q (GAL,QZS,CMP)
#define CODE_L6Z 34 //! obs code: E6A+B+C (GAL)
#define CODE_L6S 35 //! obs code: LEXS (QZS)
#define CODE_L6L 36 //! obs code: LEXL (QZS)
#define CODE_L8I 37 //! obs code: E5(a+b)I (GAL)
#define CODE_L8Q 38 //! obs code: E5(a+b)Q (GAL)
#define CODE_L8X 39 //! obs code: E5(a+b)I+Q (GAL)
#define CODE_L2I 40 //! obs code: B1I (BDS)
#define CODE_L2Q 41 //! obs code: B1Q (BDS)
#define CODE_L6I 42 //! obs code: B3I (BDS)
#define CODE_L6Q 43 //! obs code: B3Q (BDS)
#define CODE_L3I 44 //! obs code: G3I (GLO)
#define CODE_L3Q 45 //! obs code: G3Q (GLO)
#define CODE_L3X 46 //! obs code: G3I+Q (GLO)
#define CODE_L1I 47 //! obs code: B1I (BDS)
#define CODE_L1Q 48 //! obs code: B1Q (BDS)
#define CODE_L5A 49 //! obs code: L5A SPS (IRN)
#define CODE_L5B 50 //! obs code: L5B RS(D) (IRN)
#define CODE_L5C 51 //! obs code: L5C RS(P) (IRN)
#define CODE_L9A 52 //! obs code: SA SPS (IRN)
#define CODE_L9B 53 //! obs code: SB RS(D) (IRN)
#define CODE_L9C 54 //! obs code: SC RS(P) (IRN)
#define CODE_L9X 55 //! obs code: SB+C (IRN)
#define MAXCODE 55 //! max number of obs code
#define PMODE_SINGLE 0 //! positioning mode: single
#define PMODE_DGPS 1 //! positioning mode: DGPS/DGNSS
#define PMODE_KINEMA 2 //! positioning mode: kinematic
#define PMODE_STATIC 3 //! positioning mode: static
#define PMODE_MOVEB 4 //! positioning mode: moving-base
#define PMODE_FIXED 5 //! positioning mode: fixed
#define PMODE_PPP_KINEMA 6 //! positioning mode: PPP-kinemaric
#define PMODE_PPP_STATIC 7 //! positioning mode: PPP-static
#define PMODE_PPP_FIXED 8 //! positioning mode: PPP-fixed
#define SOLF_LLH 0 //! solution format: lat/lon/height
#define SOLF_XYZ 1 //! solution format: x/y/z-ecef
#define SOLF_ENU 2 //! solution format: e/n/u-baseline
#define SOLF_NMEA 3 //! solution format: NMEA-183
#define SOLF_STAT 4 //! solution format: solution status
#define SOLF_GSIF 5 //! solution format: GSI F1/F2
#define SOLQ_NONE 0 //! solution status: no solution
#define SOLQ_FIX 1 //! solution status: fix
#define SOLQ_FLOAT 2 //! solution status: float
#define SOLQ_SBAS 3 //! solution status: SBAS
#define SOLQ_DGPS 4 //! solution status: DGPS/DGNSS
#define SOLQ_SINGLE 5 //! solution status: single
#define SOLQ_PPP 6 //! solution status: PPP
#define SOLQ_DR 7 //! solution status: dead reconing
#define MAXSOLQ 7 //! max number of solution status
#define TIMES_GPST 0 //! time system: gps time
#define TIMES_UTC 1 //! time system: utc
#define TIMES_JST 2 //! time system: jst
#define IONOOPT_OFF 0 //! ionosphere option: correction off
#define IONOOPT_BRDC 1 //! ionosphere option: broadcast model
#define IONOOPT_SBAS 2 //! ionosphere option: SBAS model
#define IONOOPT_IFLC 3 //! ionosphere option: L1/L2 or L1/L5 iono-free LC
#define IONOOPT_EST 4 //! ionosphere option: estimation
#define IONOOPT_TEC 5 //! ionosphere option: IONEX TEC model
#define IONOOPT_QZS 6 //! ionosphere option: QZSS broadcast model
#define IONOOPT_LEX 7 //! ionosphere option: QZSS LEX ionospehre
#define IONOOPT_STEC 8 //! ionosphere option: SLANT TEC model
#define TROPOPT_OFF 0 //! troposphere option: correction off
#define TROPOPT_SAAS 1 //! troposphere option: Saastamoinen model
#define TROPOPT_SBAS 2 //! troposphere option: SBAS model
#define TROPOPT_EST 3 //! troposphere option: ZTD estimation
#define TROPOPT_ESTG 4 //! troposphere option: ZTD+grad estimation
#define TROPOPT_ZTD 5 //! troposphere option: ZTD correction
#define EPHOPT_BRDC 0 //! ephemeris option: broadcast ephemeris
#define EPHOPT_PREC 1 //! ephemeris option: precise ephemeris
#define EPHOPT_SBAS 2 //! ephemeris option: broadcast + SBAS
#define EPHOPT_SSRAPC 3 //! ephemeris option: broadcast + SSR_APC
#define EPHOPT_SSRCOM 4 //! ephemeris option: broadcast + SSR_COM
#define EPHOPT_LEX 5 //! ephemeris option: QZSS LEX ephemeris
#define ARMODE_OFF 0 //! AR mode: off
#define ARMODE_CONT 1 //! AR mode: continuous
#define ARMODE_INST 2 //! AR mode: instantaneous
#define ARMODE_FIXHOLD 3 //! AR mode: fix and hold
#define ARMODE_WLNL 4 //! AR mode: wide lane/narrow lane
#define ARMODE_TCAR 5 //! AR mode: triple carrier ar
#define SBSOPT_LCORR 1 //! SBAS option: long term correction
#define SBSOPT_FCORR 2 //! SBAS option: fast correction
#define SBSOPT_ICORR 4 //! SBAS option: ionosphere correction
#define SBSOPT_RANGE 8 //! SBAS option: ranging
#define POSOPT_POS 0 //! pos option: LLH/XYZ
#define POSOPT_SINGLE 1 //! pos option: average of single pos
#define POSOPT_FILE 2 //! pos option: read from pos file
#define POSOPT_RINEX 3 //! pos option: rinex header pos
#define POSOPT_RTCM 4 //! pos option: rtcm station pos
#define POSOPT_RAW 5 //! pos option: raw station pos
#define STR_NONE 0 //! stream type: none
#define STR_SERIAL 1 //! stream type: serial
#define STR_FILE 2 //! stream type: file
#define STR_TCPSVR 3 //! stream type: TCP server
#define STR_TCPCLI 4 //! stream type: TCP client
#define STR_NTRIPSVR 6 //! stream type: NTRIP server
#define STR_NTRIPCLI 7 //! stream type: NTRIP client
#define STR_FTP 8 //! stream type: ftp
#define STR_HTTP 9 //! stream type: http
#define STR_NTRIPC_S 10 //! stream type: NTRIP caster server
#define STR_NTRIPC_C 11 //! stream type: NTRIP caster client
#define STR_UDPSVR 12 //! stream type: UDP server
#define STR_UDPCLI 13 //! stream type: UDP server
#define STR_MEMBUF 14 //! stream type: memory buffer
#define STRFMT_RTCM2 0 //! stream format: RTCM 2
#define STRFMT_RTCM3 1 //! stream format: RTCM 3
#define STRFMT_OEM4 2 //! stream format: NovAtel OEMV/4
#define STRFMT_OEM3 3 //! stream format: NovAtel OEM3
#define STRFMT_UBX 4 //! stream format: u-blox LEA-*T
#define STRFMT_SS2 5 //! stream format: NovAtel Superstar II
#define STRFMT_CRES 6 //! stream format: Hemisphere
#define STRFMT_STQ 7 //! stream format: SkyTraq S1315F
#define STRFMT_GW10 8 //! stream format: Furuno GW10
#define STRFMT_JAVAD 9 //! stream format: JAVAD GRIL/GREIS
#define STRFMT_NVS 10 //! stream format: NVS NVC08C
#define STRFMT_BINEX 11 //! stream format: BINEX
#define STRFMT_RT17 12 //! stream format: Trimble RT17
#define STRFMT_SEPT 13 //! stream format: Septentrio
#define STRFMT_CMR 14 //! stream format: CMR/CMR+
#define STRFMT_TERSUS 15 //! stream format: TERSUS
#define STRFMT_LEXR 16 //! stream format: Furuno LPY-10000
#define STRFMT_RINEX 17 //! stream format: RINEX
#define STRFMT_SP3 18 //! stream format: SP3
#define STRFMT_RNXCLK 19 //! stream format: RINEX CLK
#define STRFMT_SBAS 20 //! stream format: SBAS messages
#define STRFMT_NMEA 21 //! stream format: NMEA 0183
#define MAXRCVFMT 15 //! max number of receiver format
#define STR_MODE_R 1 //! stream mode: read
#define STR_MODE_W 2 //! stream mode: write
#define STR_MODE_RW 3 //! stream mode: read/write
#define GEOID_EMBEDDED 0 //! geoid model: embedded geoid
#define GEOID_EGM96_M150 1 //! geoid model: EGM96 15x15"
#define GEOID_EGM2008_M25 2 //! geoid model: EGM2008 2.5x2.5"
#define GEOID_EGM2008_M10 3 //! geoid model: EGM2008 1.e0x1.e0"
#define GEOID_GSI2000_M15 4 //! geoid model: GSI geoid 2000 1.e0x1.5"
#define GEOID_RAF09 5 //! geoid model: IGN RAF09 for France 1.5"x2"
#define DLOPT_FORCE 1 //! download option: force download existing
#define DLOPT_KEEPCMP 2 //! download option: keep compressed file
#define DLOPT_HOLDERR 4 //! download option: hold on error file
#define DLOPT_HOLDLST 8 //! download option: hold on listing file
#define LLI_SLIP 1 //! LLI: cycle-slip
#define LLI_HALFC 2 //! LLI: half-cycle not resovled
#define LLI_BOCTRK 4 //! LLI: boc tracking of mboc signal
#define LLI_HALFA 64 //! LLI: half-cycle added
#define LLI_HALFS 128 //! LLI: half-cycle subtracted
#define IMUFMT_KVH 1 //! imu data format KVH
#define FPOUT 10 //! solution files (except for 1/2/5/6)
#define FPREAD 11 //! obs/nav files
#define FPOPT 12 //! option files
#define FPADD 13 //! additional files
#define FPCLK 14 //! additional files (sat clock bias)
#define FPPOS 15 //! additional files (sat pos)
#define MAX_ITER_KEPLER 30 //! max number of iteration of Kelpler
#define NX (4+3) //! # of estimated parameters
#define MAXITR 10 //! max number of iteration for point pos
//! rinex.f90 -----------------------------------------------------------------
#define NUMSYS 7 //! number of systems
#define MAXRNXLEN (16*MAXOBSTYPE+4) //! max rinex record length
#define MAXPOSHEAD 1024 //! max head line position
#define MINFREQ_GLO -7 //! min frequency number glonass
#define MAXFREQ_GLO 13 //! max frequency number glonass
#define NINCOBS 262144/2 //! inclimental number of obs data
//! postpos.f90 ---------------------------------------------------------------
#define MAXINFILE 1000 //! max number of input files
//! rnx2rtkp.f90 --------------------------------------------------------------
#define MAXFILE 16 //! max number of input files
#define FLNUMLIM 200 //! max number of rnxlist
extern const double PI; //! pi
extern const double D2R; //! deg to rad
extern const double R2D; //! rad to deg
extern const double CLIGHT; //! speed of light (m/s)
extern const double SC2RAD; //! semi-circle to radian (IS-GPS)
extern const double AU; //! 1 AU (m)
extern const double AS2R; //! arc sec to radian
extern const double OMGE; //! earth angular velocity (IS-GPS) (rad/s)
extern const double RE_WGS84; //! earth semimajor axis (WGS84) (m)
extern const double FE_WGS84; //! earth flattening (WGS84)
extern const double HION; //! ionosphere height (m)
extern const double FREQL1; //! L1/E1 frequency (Hz)
extern const double FREQL2; //! L2 frequency (Hz)
extern const double FREQL5; //! L5/E5a frequency (Hz)
extern const double FREQL6; //! E6/LEX frequency (Hz)
extern const double FREQE5b; //! E5b frequency (Hz)
extern const double FREQE5ab; //! E5a+b frequency (Hz)
extern const double FREQs; //! S frequency (Hz)
extern const double FREQ1_GLO; //! GLONASS G1 base frequency (Hz)
extern const double DFRQ1_GLO; //! GLONASS G1 bias frequency (Hz/n)
extern const double FREQ2_GLO; //! GLONASS G2 base frequency (Hz)
extern const double DFRQ2_GLO; //! GLONASS G2 bias frequency (Hz/n)
extern const double FREQ1a_GLO; // GLONASS G1a frequency (Hz)
extern const double FREQ2a_GLO; // GLONASS G2a frequency (Hz)
extern const double FREQ3_GLO; //! GLONASS G3 frequency (Hz)
extern const double FREQ1_CMP; //! BeiDou B1 frequency (Hz)
extern const double FREQ2_CMP; //! BeiDou B2 frequency (Hz)
extern const double FREQ3_CMP; //! BeiDou B3 frequency (Hz)
extern const double EFACT_GPS; //! error factor: GPS
extern const double EFACT_GLO; //! error factor: GLONASS
extern const double EFACT_GAL; //! error factor: Galileo
extern const double EFACT_QZS; //! error factor: QZSS
extern const double EFACT_CMP; //! error factor: BeiDou
extern const double EFACT_IRN; //! error factor: IRNSS
extern const double EFACT_SBS; //! error factor: SBAS
extern const double DTTOL; //! tolerance of time difference (s)
extern const double MAXDTOE; //! max time difference to GPS Toe (s)
extern const double MAXDTOE_QZS; //! max time difference to QZSS Toe (s)
extern const double MAXDTOE_GAL; //! max time difference to Galileo Toe (s)
extern const double MAXDTOE_CMP; //! max time difference to BeiDou Toe (s)
extern const double MAXDTOE_GLO; //! max time difference to GLONASS Toe (s)
extern const double MAXDTOE_SBS; //! max time difference to SBAS Toe (s)
extern const double MAXDTOE_S; //! max time difference to ephem toe (s) for other
extern const double MAXGDOP; //! max GDOP
extern const double INT_SWAP_TRAC; //! swap interval of trace file (s)
extern const double INT_SWAP_STAT; //! swap interval of solution status file (s)
extern const double MAXSBSAGEF; //! max age of SBAS fast correction (s)
extern const double MAXSBSAGEL; //! max age of SBAS long term corr (s)
extern const double RNX2VER; //! RINEX ver.2 default output version
extern const double RNX3VER; //! RINEX ver.3 default output version
extern const char COMMENTH[2]; //! comment line indicator for solution
extern const char MSG_DISCONN[13]; //! disconnect message
extern const double P2_5; //! 2^-5
extern const double P2_6; //! 2^-6
extern const double P2_11; //! 2^-11
extern const double P2_15; //! 2^-15
extern const double P2_17; //! 2^-17
extern const double P2_19; //! 2^-19
extern const double P2_20; //! 2^-20
extern const double P2_21; //! 2^-21
extern const double P2_23; //! 2^-23
extern const double P2_24; //! 2^-24
extern const double P2_27; //! 2^-27
extern const double P2_29; //! 2^-29
extern const double P2_30; //! 2^-30
extern const double P2_31; //! 2^-31
extern const double P2_32; //! 2^-32
extern const double P2_33; //! 2^-33
extern const double P2_35; //! 2^-35
extern const double P2_38; //! 2^-38
extern const double P2_39; //! 2^-39
extern const double P2_40; //! 2^-40
extern const double P2_43; //! 2^-43
extern const double P2_48; //! 2^-48
extern const double P2_50; //! 2^-50
extern const double P2_55; //! 2^-55
//! rtkcmn.f90 ----------------------------------------------------------------
extern const double MAX_VAR_EPH; //! max variance eph to reject satellite (m^2)
extern const double gpst0[6]; //! gps time reference
extern const double gst0[6]; //! galileo system time reference
extern const double bdt0[6]; //! beidou time reference
extern const double lam_carr[MAXFREQ];
//! leap seconds (y,m,d,h,m,s,utc-gpst)
extern const double leaps[19][7];
//! observation code strings
extern const char obscodes[60][3];
//! 1:L1/E1, 2:L2/B1, 3:L5/E5a/L3, 4:L6/LEX/B3, 5:E5b/B2, 6:E5(a+b), 7:S
extern const int obsfreqs[60];
//! code priority table
//! L1/E1; L2/B1; L5/E5a/L3; L6/LEX/B3; E5b/B2; E5(a+b); S
extern const char codepris[7][MAXFREQ][17];
//! ephemeris.f90 -------------------------------------------------------------
extern const double RE_GLO; //! radius of earth (m) ref (2)
extern const double MU_GPS; //! gravitational externant ref (1)
extern const double MU_GLO; //! gravitational externant ref (2)
extern const double MU_GAL; //! earth gravitational externant ref (7)
extern const double MU_CMP; //! earth gravitational externant ref (9)
extern const double J2_GLO; //! 2nd zonal harmonic of geopot ref (2)
extern const double OMGE_GLO; //! earth angular velocity (rad/s) ref (2)
extern const double OMGE_GAL; //! earth angular velocity (rad/s) ref (7)
extern const double OMGE_CMP; //! earth angular velocity (rad/s) ref (9)
extern const double SIN_5; //! dsin(-5.e0 deg)
extern const double COS_5; //! dcos(-5.e0 deg)
extern const double ERREPH_GLO; //! error of glonass ephemeris (m)
extern const double TSTEP; //! integration step glonass ephemeris (s)
extern const double RTOL_KEPLER; //! relative tolerance for Kepler equation
extern const double DEFURASSR; //! default accurary of ssr corr (m)
extern const double MAXECORSSR; //! max orbit correction of ssr (m)
extern const double MAXCCORSSR; //! max clock correction of ssr (m)
extern const double MAXAGESSR; //! max age of ssr orbit and clock (s)
extern const double MAXAGESSR_HRCLK; //! max age of ssr high-rate clock (s)
extern const double STD_BRDCCLK; //! error of broadcast clock (m)
extern const double STD_GAL_NAPA; //! error of galileo ephemeris for NAPA (m)
extern const int eph_sel[6]; //! GPS,GLO,GAL,QZS,BDS,SBS (ephemeris selections)
//! pntpos.f90 ----------------------------------------------------------------
extern const double ERR_ION; //! ionospheric delay std (m)
extern const double ERR_TROP; //! tropspheric delay std (m)
extern const double ERR_SAAS; //! saastamoinen model error std (m)
extern const double ERR_BRDCI; //! broadcast iono model error factor
extern const double ERR_CBIAS; //! code bias error std (m)
extern const double REL_HUMI; //! relative humidity for saastamoinen model
extern const char systyps[8]; //! satellite system codes
extern const char obstyps[5]; //! obs type codes
extern const char frqtyps[8]; //! frequency codes
extern const double ura_eph[16]; //! ura values (ref [3] 20.3.3.3.1.1)
extern const double ura_nominal[16]; //! ura nominal values
#endif

455
src/decodenav.c Normal file
View File

@ -0,0 +1,455 @@
#include <stdlib.h>
#include "decodenav.h"
#include "str.h"
#include "timeconvert.h"
/* URA value (m) to URA index ------------------------------------------------*/
static int uraindex(double value)
{
int i;
for (i = 0; i < 15; i++){
if (ura_eph[i] >= value) break;
}
return i;
}
/* Galileo SISA value (m) to SISA index --------------------------------------*/
static int sisa_index(double value)
{
/*
* kudos to https://core.ac.uk/download/pdf/328854682.pdf for this ...
* Signal-in-Space Accuracy : SISA flag is a prediction at 1-sigma standard deviation of the quality of
* the transmitted signal.The flag can take values from 0 to 255. The transmitted standard index is 107 that
* corresponds to a SISA value of 3.12m.If the prediction is not available, the transmitted index is 255 and
* corresponds to No Accurate Prediction Available(NAPA).NAPA is an indicator of a potential anomalous
* signal-in-space[6].Please notice that SISA flag refers to the dual-frequency signal combinations.
*/
if (value < 0.0 || value > 6.0)
return 255; /* unknown or NAPA */
else if (value <= 0.5)
return (int)(value / 0.01);
else if (value <= 1.0)
return (int)((value - 0.5) / 0.02) + 50;
else if (value <= 2.0)
return (int)((value - 1.0) / 0.04) + 75;
return (int)((value - 2.0) / 0.16) + 100;
}
void decode_navh(char *buff, nav_t *nav)
{
int i,j;
char* label = buff + 60;
if (strstr(label, "ION ALPHA"))
{ /* opt ver.2 */
if (nav)
{
for (i = 0, j = 2; i < 4; i++, j += 12)
{
nav->ion_gps[i] = str2num(buff, j, 12);
}
}
}
else if (strstr(label, "ION BETA"))
{ /* opt ver.2 */
if (nav)
{
for (i = 0, j = 2; i < 4; i++, j += 12)
{
nav->ion_gps[i + 4] = str2num(buff, j, 12);
}
}
}
else if (strstr(label, "DELTA-UTC: A0,A1,T,W"))
{ /* opt ver.2 */
if (nav)
{
for (i = 0, j = 3; i < 2; i++, j += 19)
{
nav->utc_gps[i] = str2num(buff, j, 19);
}
for (; i < 4; i++, j += 9)
{
nav->utc_gps[i] = str2num(buff, j, 9);
}
}
}
else if (strstr(label, "IONOSPHERIC CORR"))
{ /* opt ver.3 */
if (nav)
{
if (!strncmp(buff, "GPSA", 4))
{
for (i = 0, j = 5; i < 4; i++, j += 12)
{
nav->ion_gps[i] = str2num(buff, j, 12);
}
}
else if (!strncmp(buff, "GPSB", 4))
{
for (i = 0, j = 5; i < 4; i++, j += 12)
{
nav->ion_gps[i + 4] = str2num(buff, j, 12);
}
}
else if (!strncmp(buff, "GAL", 3))
{
for (i = 0, j = 5; i < 4; i++, j += 12)
{
nav->ion_gal[i] = str2num(buff, j, 12);
}
}
else if (!strncmp(buff, "QZSA", 4))
{ /* v.3.02 */
for (i = 0, j = 5; i < 4; i++, j += 12)
{
nav->ion_qzs[i] = str2num(buff, j, 12);
}
}
else if (!strncmp(buff, "QZSB", 4))
{ /* v.3.02 */
for (i = 0, j = 5; i < 4; i++, j += 12)
{
nav->ion_qzs[i + 4] = str2num(buff, j, 12);
}
}
else if (!strncmp(buff, "BDSA", 4))
{ /* v.3.02 */
for (i = 0, j = 5; i < 4; i++, j += 12)
{
nav->ion_cmp[i] = str2num(buff, j, 12);
}
}
else if (!strncmp(buff, "BDSB", 4))
{ /* v.3.02 */
for (i = 0, j = 5; i < 4; i++, j += 12)
{
nav->ion_cmp[i + 4] = str2num(buff, j, 12);
}
}
else if (!strncmp(buff, "IRNA", 4))
{ /* v.3.03 */
for (i = 0, j = 5; i < 4; i++, j += 12)
{
nav->ion_irn[i] = str2num(buff, j, 12);
}
}
else if (!strncmp(buff, "IRNB", 4))
{ /* v.3.03 */
for (i = 0, j = 5; i < 4; i++, j += 12)
{
nav->ion_irn[i + 4] = str2num(buff, j, 12);
}
}
}
}
else if (strstr(label, "TIME SYSTEM CORR"))
{ /* opt ver.3 */
if (nav)
{
if (!strncmp(buff, "GPUT", 4))
{
nav->utc_gps[0] = str2num(buff, 5, 17);
nav->utc_gps[1] = str2num(buff, 22, 16);
nav->utc_gps[2] = str2num(buff, 38, 7);
nav->utc_gps[3] = str2num(buff, 45, 5);
}
else if (!strncmp(buff, "GLUT", 4))
{
nav->utc_glo[0] = -str2num(buff, 5, 17); /* tau_C */
}
else if (!strncmp(buff, "GLGP", 4))
{
nav->utc_glo[1] = str2num(buff, 5, 17); /* tau_GPS */
}
else if (!strncmp(buff, "GAUT", 4))
{ /* v.3.02 */
nav->utc_gal[0] = str2num(buff, 5, 17);
nav->utc_gal[1] = str2num(buff, 22, 16);
nav->utc_gal[2] = str2num(buff, 38, 7);
nav->utc_gal[3] = str2num(buff, 45, 5);
}
else if (!strncmp(buff, "QZUT", 4))
{ /* v.3.02 */
nav->utc_qzs[0] = str2num(buff, 5, 17);
nav->utc_qzs[1] = str2num(buff, 22, 16);
nav->utc_qzs[2] = str2num(buff, 38, 7);
nav->utc_qzs[3] = str2num(buff, 45, 5);
}
else if (!strncmp(buff, "BDUT", 4))
{ /* v.3.02 */
nav->utc_cmp[0] = str2num(buff, 5, 17);
nav->utc_cmp[1] = str2num(buff, 22, 16);
nav->utc_cmp[2] = str2num(buff, 38, 7);
nav->utc_cmp[3] = str2num(buff, 45, 5);
}
else if (!strncmp(buff, "SBUT", 4))
{ /* v.3.02 */
nav->utc_sbs[0] = str2num(buff, 5, 17);
nav->utc_sbs[1] = str2num(buff, 22, 16);
nav->utc_sbs[2] = str2num(buff, 38, 7);
nav->utc_sbs[3] = str2num(buff, 45, 5);
}
else if (!strncmp(buff, "IRUT", 4))
{ /* v.3.03 */
nav->utc_irn[0] = str2num(buff, 5, 17);
nav->utc_irn[1] = str2num(buff, 22, 16);
nav->utc_irn[2] = str2num(buff, 38, 7);
nav->utc_irn[3] = str2num(buff, 45, 5);
}
}
}
else if (strstr(label, "LEAP SECONDS"))
{ /* opt */
if (nav)
{
nav->leaps = (int)str2num(buff, 0, 6);
}
}
return;
}
void decode_gnavh(char *buff, nav_t *nav)
{
char *label = buff + 60;
if (strstr(label, "CORR TO SYSTEM TIME"));
else if (strstr(label, "LEAP SECONDS"))
{
if (nav)
{
nav->leaps = (int)str2num(buff, 0, 6);
}
}
}
int decode_geph(double ver, int sat, gtime_t toc, double *data, geph_t *geph)
{
geph_t geph0 = {0};
gtime_t tof;
double tow, tod;
int week, dow;
printf("decode_geph: ver=%.2f sat=%2d\n", ver, sat);
if (satsys(sat, NULL) != SYS_GLO)
{
printf("glonass ephemeris error: invalid satellite sat=%2d\n", sat);
return 0;
}
*geph = geph0;
geph->sat = sat;
/* Toc rounded by 15 min in utc */
tow = time2gpst(toc, &week);
toc = gpst2time(week, floor((tow + 450.0) / 900.0) * 900);
dow = (int)floor(tow / 86400.0);
/* time of frame in UTC */
tod = ver <= 2.99 ? data[2] : fmod(data[2], 86400.0); /* Tod (v.2), Tow (v.3) in UTC */
tof = gpst2time(week, tod + dow * 86400.0);
tof = adjday(tof, toc);
geph->toe = utc2gpst(toc); /* Toc (GPST) */
geph->tof = utc2gpst(tof); /* Tof (GPST) */
/* IODE = Tb (7bit), Tb =index of UTC+3H within current day */
geph->iode = (int)(fmod(tow + 10800.0, 86400.0) / 900.0 + 0.5);
geph->taun = -data[0]; /* -taun */
geph->gamn = data[1]; /* +gamman */
geph->pos[0] = data[3] * 1E3;
geph->pos[1] = data[7] * 1E3;
geph->pos[2] = data[11] * 1E3;
geph->vel[0] = data[4] * 1E3;
geph->vel[1] = data[8] * 1E3;
geph->vel[2] = data[12] * 1E3;
geph->acc[0] = data[5] * 1E3;
geph->acc[1] = data[9] * 1E3;
geph->acc[2] = data[13] * 1E3;
geph->svh = (int)data[6];
geph->frq = (int)data[10];
geph->age = (int)data[14];
/* some receiver output >128 for minus frequency number */
if (geph->frq > 128)
geph->frq -= 256;
if (geph->frq < MINFREQ_GLO || MAXFREQ_GLO < geph->frq)
{
printf("rinex gnav invalid freq: sat=%2d fn=%d\n", sat, geph->frq);
}
return 1;
}
int decode_seph(double ver, int sat, gtime_t toc, double *data,seph_t *seph)
{
seph_t seph0 = {0};
int week;
printf("decode_seph: ver=%.2f sat=%2d\n", ver, sat);
if (satsys(sat, NULL) != SYS_SBS)
{
printf("geo ephemeris error: invalid satellite sat=%2d\n", sat);
return 0;
}
*seph = seph0;
seph->sat = sat;
seph->t0 = toc;
time2gpst(toc, &week);
seph->tof = adjweek(gpst2time(week, data[2]), toc);
seph->af0 = data[0];
seph->af1 = data[1];
seph->pos[0] = data[3] * 1E3;
seph->pos[1] = data[7] * 1E3;
seph->pos[2] = data[11] * 1E3;
seph->vel[0] = data[4] * 1E3;
seph->vel[1] = data[8] * 1E3;
seph->vel[2] = data[12] * 1E3;
seph->acc[0] = data[5] * 1E3;
seph->acc[1] = data[9] * 1E3;
seph->acc[2] = data[13] * 1E3;
seph->svh = (int)data[6];
seph->sva = uraindex(data[10]);
return 1;
}
int decode_eph(double ver, int sat, gtime_t toc, const double *data,
eph_t *eph)
{
eph_t eph0 = {0};
int sys;
printf("decode_eph: ver=%.2f sat=%2d\n", ver, sat);
sys = satsys(sat, NULL);
if (!(sys & (SYS_GPS | SYS_GAL | SYS_QZS | SYS_CMP | SYS_IRN)))
{
printf("ephemeris error: invalid satellite sat=%2d\n", sat);
return 0;
}
*eph = eph0;
eph->sat = sat;
eph->toc = toc;
eph->f0 = data[0];
eph->f1 = data[1];
eph->f2 = data[2];
eph->A = data[10]*data[10];
eph->e = data[8];
eph->i0 = data[15];
eph->OMG0 = data[13];
eph->omg = data[17];
eph->M0 = data[6];
eph->deln = data[5];
eph->OMGd = data[18];
eph->idot = data[19];
eph->crc = data[16];
eph->crs = data[4];
eph->cuc = data[7];
eph->cus = data[9];
eph->cic = data[12];
eph->cis = data[14];
if (sys == SYS_GPS || sys == SYS_QZS)
{
eph->iode = (int)data[3]; /* IODE */
eph->iodc = (int)data[26]; /* IODC */
eph->toes = data[11]; /* Toe (s) in GPS week */
eph->week = (int)data[21]; /* GPS week */
eph->toe = adjweek(gpst2time(eph->week, data[11]), toc);
eph->ttr = adjweek(gpst2time(eph->week, data[27]), toc);
eph->code = (int)data[20]; /* GPS: codes on L2 ch */
eph->svh = (int)data[24]; /* SV health */
eph->sva = uraindex(data[23]); /* URA index (m->index) */
eph->flag = (int)data[22]; /* GPS: L2 P data flag */
eph->tgd[0] = data[25]; /* TGD */
if (sys == SYS_GPS)
{
eph->fit = data[28]; /* fit interval (h) */
}
else
{
eph->fit = data[28] == 0.0 ? 1.0 : 2.0; /* fit interval (0:1h,1:>2h) */
}
}
else if (sys == SYS_GAL)
{ /* GAL ver.3 */
eph->iode = (int)data[3]; /* IODnav */
eph->toes = data[11]; /* Toe (s) in Galileo week */
eph->week = (int)data[21]; /* Galileo week = GPS week */
eph->toe = adjweek(gpst2time(eph->week, data[11]), toc);
eph->ttr = adjweek(gpst2time(eph->week, data[27]), toc);
eph->code = (int)data[20]; /* data sources */
/* bit 0 set: I/NAV E1-B */
/* bit 1 set: F/NAV E5a-I */
/* bit 2 set: F/NAV E5b-I */
/* bit 8 set: af0-af2 toc are for E5a.E1 */
/* bit 9 set: af0-af2 toc are for E5b.E1 */
eph->svh = (int)data[24]; /* sv health */
/* bit 0: E1B DVS */
/* bit 1-2: E1B HS */
/* bit 3: E5a DVS */
/* bit 4-5: E5a HS */
/* bit 6: E5b DVS */
/* bit 7-8: E5b HS */
eph->sva = sisa_index(data[23]); /* sisa (m->index) */
eph->tgd[0] = data[25]; /* BGD E5a/E1 */
eph->tgd[1] = data[26]; /* BGD E5b/E1 */
}
else if (sys == SYS_CMP)
{ /* BeiDou v.3.02 */
eph->toc = bdt2gpst(eph->toc); /* bdt -> gpst */
eph->iode = (int)data[3]; /* AODE */
eph->iodc = (int)data[28]; /* AODC */
eph->toes = data[11]; /* Toe (s) in BDT week */
eph->week = (int)data[21]; /* bdt week */
eph->toe = bdt2gpst(bdt2time(eph->week, data[11])); /* BDT -> GPST */
eph->ttr = bdt2gpst(bdt2time(eph->week, data[27])); /* BDT -> GPST */
eph->toe = adjweek(eph->toe, toc);
eph->ttr = adjweek(eph->ttr, toc);
eph->svh = (int)data[24]; /* satH1 */
eph->sva = uraindex(data[23]); /* URA index (m->index) */
eph->tgd[0] = data[25]; /* TGD1 B1/B3 */
eph->tgd[1] = data[26]; /* TGD2 B2/B3 */
}
else if (sys == SYS_IRN)
{ /* IRNSS v.3.03 */
eph->iode = (int)data[3]; /* IODEC */
eph->toes = data[11]; /* Toe (s) in IRNSS week */
eph->week = (int)data[21]; /* IRNSS week */
eph->toe = adjweek(gpst2time(eph->week, data[11]), toc);
eph->ttr = adjweek(gpst2time(eph->week, data[27]), toc);
eph->svh = (int)data[24]; /* SV health */
eph->sva = uraindex(data[23]); /* URA index (m->index) */
eph->tgd[0] = data[25]; /* TGD */
}
if (eph->iode < 0 || 1023 < eph->iode)
{
printf("rinex nav invalid: sat=%2d iode=%d\n", sat, eph->iode);
}
if (eph->iodc < 0 || 1023 < eph->iodc)
{
printf("rinex nav invalid: sat=%2d iodc=%d\n", sat, eph->iodc);
}
return 1;
}

20
src/decodenav.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef DECODENAV_H
#define DECODENAV_H
#include "comtyp.h"
/* decode RINEX NAV header ---------------------------------------------------*/
void decode_navh(char *buff, nav_t *nav);
/* decode GNAV header --------------------------------------------------------*/
void decode_gnavh(char *buff, nav_t *nav);
/* decode GLONASS ephemeris --------------------------------------------------*/
int decode_geph(double ver, int sat, gtime_t toc, double *data,geph_t *geph);
/* decode GEO ephemeris ------------------------------------------------------*/
int decode_seph(double ver, int sat, gtime_t toc, double *data,seph_t *seph);
/* decode ephemeris ----------------------------------------------------------*/
int decode_eph(double ver, int sat, gtime_t toc, const double *data,eph_t *eph);
#endif

490
src/decodeobs.c Normal file
View File

@ -0,0 +1,490 @@
#include "decodeobs.h"
#include "str.h"
#include "obscode.h"
decode_obsh(FILE *fp, char *buff, double ver, int *tsys,
char tobs[][MAXOBSTYPE][4],obs_t* obs, nav_t *nav, sta_t *sta)
{
// default codes for unknown code
char defcodes[7][8]={
"CWX ", // GPS: L125____
"CC ", // GLO: L12_____
"X XXXX ", // GAL: L1_5678_
"CXXX ", // QZS: L1256___
"C X ", // SBS: L1_5____
"XIXIIX ", // BDS: L125678_
" A A"}; // IRN: L__5___9
double del[3];
int i,j,k,n,nt,prn,fcn;
char* p;
char* label = buff + 60;
char str[4];
if (strstr(label, "MARKER NUMBER"))
{
if(sta) setstr(sta->name, buff, 60);
}
else if (strstr(label, "MARKER NUMBER"))
{
if(sta) setstr(sta->marker, buff, 20);
}
else if (strstr(label, "MARKER TYPE"));
else if (strstr(label, "OBSERVER / AGENCY"));
else if (strstr(label, "REC # / TYPE / VERS"))
{
if(sta)
{
setstr(sta->recsno, buff, 20);
setstr(sta->rectype, buff + 20, 20);
setstr(sta->recver, buff + 40, 20);
}
}
else if (strstr(label, "ANT # / TYPE"))
{
if (sta)
{
setstr(sta->antsno, buff, 20);
setstr(sta->antdes, buff + 20, 20);
}
}
else if (strstr(label, "APPROX POSITION XYZ"))
{
if (sta)
{
for (i = 0, j = 0; i < 3; i++, j += 14)
{
sta->pos[i] = str2num(buff, j, 14);
}
}
}
else if (strstr(label, "ANTENNA: DELTA H/E/N"))
{
if (sta)
{
for (i = 0, j = 0; i < 3; i++, j += 14)
{
del[i] = str2num(buff, j, 14);
}
sta->del[2] = del[0]; /* h */
sta->del[0] = del[1]; /* e */
sta->del[1] = del[2]; /* n */
}
}
else if(strstr(label,"ANTENNA: DELTA X/Y/Z")); // opt ver.3
else if(strstr(label,"ANTENNA: PHASECENTER")); // opt ver.3
else if(strstr(label,"ANTENNA: B.SIGHT XYZ")); // opt ver.3
else if(strstr(label,"ANTENNA: ZERODIR AZI")); // opt ver.3
else if(strstr(label,"ANTENNA: ZERODIR XYZ")); // opt ver.3
else if(strstr(label,"CENTER OF MASS: XYZ" )); // opt ver.3
else if(strstr(label,"SYS / # / OBS TYPES" )) // ver.3
{
if (!(p = strchr(systyps, buff[0])))
{
printf("invalid system code: sys=%c\n", buff[0]);
return;
}
i = (int)(p - systyps);
n = (int)str2num(buff, 3, 3);
for (j = nt = 0, k = 7; j < n; j++, k += 4)
{
if (k > 58)
{
if (!fgets(buff, MAXRNXLEN, fp))
break;
k = 7;
}
if (nt < MAXOBSTYPE - 1)
setstr(tobs[i][nt++], buff + k, 3);
}
*tobs[i][nt] = '\0';
/* change BDS B1 code: 3.02 */
if (i == 5 && fabs(ver - 3.02) < 1e-3)
{
for (j = 0; j < nt; j++)
if (tobs[i][j][1] == '1')
tobs[i][j][1] = '2';
}
for (j=0;j<nt;j++) {
if (tobs[i][j][2]) continue;
if (!(p=strchr(frqtyps,tobs[i][j][1]))) continue;
tobs[i][j][2]=defcodes[i][(int)(p-frqtyps)];
printf("set default for unknown code: sys=%c code=%s\n",buff[0],
tobs[i][j]);
}
}
else if (strstr(label, "WAVELENGTH FACT L1/2")); /* opt ver.2 */
else if (strstr(label, "# / TYPES OF OBSERV"))
{ /* ver.2 */
n = (int)str2num(buff, 0, 6);
for (i = nt = 0, j = 10; i < n; i++, j += 6)
{
if (j > 58)
{
if (!fgets(buff, MAXRNXLEN, fp))
break;
j = 10;
}
if (nt >= MAXOBSTYPE - 1)
continue;
if (ver <= 2.99)
{
setstr(str, buff + j, 2);
convcode(ver, SYS_GPS, str, tobs[0][nt]);
convcode(ver, SYS_GLO, str, tobs[1][nt]);
convcode(ver, SYS_GAL, str, tobs[2][nt]);
convcode(ver, SYS_QZS, str, tobs[3][nt]);
convcode(ver, SYS_SBS, str, tobs[4][nt]);
convcode(ver, SYS_CMP, str, tobs[5][nt]);
}
nt++;
}
*tobs[0][nt] = '\0';
}
else if (strstr(label, "SIGNAL STRENGTH UNIT")); /* opt ver.3 */
else if (strstr(label, "INTERVAL"))
{
obs->tint = str2num(buff,0,11);
}
else if (strstr(label, "TIME OF FIRST OBS"))
{
if (!strncmp(buff + 48, "GPS", 3))
*tsys = TSYS_GPS;
else if (!strncmp(buff + 48, "GLO", 3))
*tsys = TSYS_UTC;
else if (!strncmp(buff + 48, "GAL", 3))
*tsys = TSYS_GAL;
else if (!strncmp(buff + 48, "QZS", 3))
*tsys = TSYS_QZS; /* ver.3.02 */
else if (!strncmp(buff + 48, "BDT", 3))
*tsys = TSYS_CMP; /* ver.3.02 */
else if (!strncmp(buff + 48, "IRN", 3))
*tsys = TSYS_IRN; /* ver.3.03 */
}
else if (strstr(label, "TIME OF LAST OBS"));
else if (strstr(label, "RCV CLOCK OFFS APPL"));
else if (strstr(label, "SYS / DCBS APPLIED"));
else if (strstr(label, "SYS / PCVS APPLIED"));
else if (strstr(label, "SYS / SCALE FACTOR"));
else if (strstr(label, "SYS / PHASE SHIFTS")); /* ver.3.01 */
else if (strstr(label, "GLONASS SLOT / FRQ #"))
{ /* ver.3.02 */
for (i = 0; i < 8; i++)
{
if (buff[4 + i * 7] != 'R')
continue;
prn = (int)str2num(buff, 5 + i * 7, 2);
fcn = (int)str2num(buff, 8 + i * 7, 2);
if (prn < 1 || prn > MAXPRNGLO || fcn < -7 || fcn > 6)
continue;
if (nav)
nav->glo_fcn[prn - 1] = fcn + 8;
}
}
else if (strstr(label, "GLONASS COD/PHS/BIS"))
{ /* ver.3.02 */
if (nav)
{
nav->glo_cpbias[0] = str2num(buff, 5, 8);
nav->glo_cpbias[1] = str2num(buff, 18, 8);
nav->glo_cpbias[2] = str2num(buff, 31, 8);
nav->glo_cpbias[3] = str2num(buff, 44, 8);
}
}
else if (strstr(label, "LEAP SECONDS"))
{ /* opt */
if (nav)
{
/*nav->utc_gps[4] = str2num(buff, 0, 6);
nav->utc_gps[7] = str2num(buff, 6, 6);
nav->utc_gps[5] = str2num(buff, 12, 6);
nav->utc_gps[6] = str2num(buff, 18, 6);*/
nav->leaps = (int)str2num(buff,0,6);
}
}
else if (strstr(label, "# OF SATELLITES"));
else if (strstr(label, "PRN / # OF OBS"));
return;
}
int decode_obsepoch(FILE *fp, char *buff, double ver, gtime_t *time,
int *flag, int *sats)
{
int i, j, n;
char satid[8] = {'\0'};
printf("decode_obsepoch: ver=%.2f\n", ver);
if (ver <= 2.99)
{ /* ver.2 */
/* epoch flag: 3:new site,4:header info,5:external event */
*flag = (int)str2num(buff, 28, 1);
/* handle external event */
if (*flag == 5)
{
str2time(buff, 0, 26, time);
}
if ((n = (int)str2num(buff, 29, 3)) <= 0)
return 0;
if (3 <= *flag && *flag <= 5)
return n;
if (str2time(buff, 0, 26, time))
{
printf("rinex obs invalid epoch: epoch=%26.26s\n", buff);
return 0;
}
for (i = 0, j = 32; i < n; i++, j += 3)
{
if (j >= 68)
{
if (!fgets(buff, MAXRNXLEN, fp))
break;
j = 32;
}
if (i < MAXOBS)
{
strncpy(satid, buff + j, 3);
sats[i] = satid2no(satid);
}
}
}
else
{ /* ver.3 */
*flag = (int)str2num(buff, 31, 1);
/* handle external event */
if (*flag == 5)
{
str2time(buff, 1, 28, time);
}
if ((n = (int)str2num(buff, 32, 3)) <= 0)
return 0;
if (3 <= *flag && *flag <= 5)
return n;
if (buff[0] != '>' || str2time(buff, 1, 28, time))
{
printf("rinex obs invalid epoch: epoch=%29.29s\n", buff);
return 0;
}
}
char time_str[64];
time2str(*time, time_str, 3);
printf("decode_obsepoch: time=%s flag=%d\n", time_str, *flag);
return n;
}
int decode_obsdata(FILE *fp, char *buff, double ver, int mask,
sigind_t *index, obsd_t *obs)
{
sigind_t *ind;
double val[MAXOBSTYPE] = {0};
unsigned char lli[MAXOBSTYPE] = {0};
unsigned char std[MAXOBSTYPE] = {0};
char satid[8] = "";
int i, j, n, m, q, status = 1, p[MAXOBSTYPE], k[16], l[16], r[16];
if (ver > 2.99)
{ /* ver.3 */
sprintf(satid, "%.3s", buff);
obs->sat = (unsigned char)satid2no(satid);
}
if (!obs->sat)
{
printf("decode_obsdata: unsupported sat sat=%s\n", satid);
status = 0;
}
else if (!(satsys(obs->sat, NULL) & mask))
{
status = 0;
}
/* read observation data fields */
switch (satsys(obs->sat, NULL))
{
case SYS_GLO:
ind = index + 1;
break;
case SYS_GAL:
ind = index + 2;
break;
case SYS_QZS:
ind = index + 3;
break;
case SYS_SBS:
ind = index + 4;
break;
case SYS_CMP:
ind = index + 5;
break;
case SYS_IRN:
ind = index + 6;
break;
default:
ind = index;
break;
}
for (i = 0, j = ver <= 2.99 ? 0 : 3; i < ind->n; i++, j += 16)
{
if (ver <= 2.99 && j >= 80)
{ /* ver.2 */
if (!fgets(buff, MAXRNXLEN, fp))
break;
j = 0;
}
if (status)
{
val[i] = str2num(buff, j, 14) + ind->shift[i];
lli[i] = (unsigned char)str2num(buff, j + 14, 1) & 3;
/* measurement std from receiver */
std[i] = (unsigned char)str2num(buff, j + 15, 1);
}
}
if (!status)
return 0;
for (i = 0; i < NFREQ + NEXOBS; i++)
{
obs->P[i] = obs->L[i] = 0.0;
obs->D[i] = 0.0f;
obs->SNR[i] = obs->LLI[i] = obs->qualL[i] = obs->qualP[i] = obs->code[i] = 0;
}
/* assign position in observation data */
for (i = n = m = q = 0; i < ind->n; i++)
{
p[i] = ind->frqIdx[i];
if (ind->type[i] == 0 && p[i] == 0)
k[n++] = i; /* C1? index */
if (ind->type[i] == 0 && p[i] == 1)
l[m++] = i; /* C2? index */
if (ind->type[i] == 0 && p[i] == 2)
r[q++] = i; /* C3? index */
}
/* if multiple codes (C1/P1,C2/P2), select higher priority */
if (n >= 2)
{
if (val[k[0]] == 0.0 && val[k[1]] == 0.0)
{
p[k[0]] = -1;
p[k[1]] = -1;
}
else if (val[k[0]] != 0.0 && val[k[1]] == 0.0)
{
p[k[0]] = 0;
p[k[1]] = -1;
}
else if (val[k[0]] == 0.0 && val[k[1]] != 0.0)
{
p[k[0]] = -1;
p[k[1]] = 0;
}
else if (ind->pri[k[1]] > ind->pri[k[0]])
{
p[k[1]] = 0;
p[k[0]] = NEXOBS < 1 ? -1 : NFREQ;
}
else
{
p[k[0]] = 0;
p[k[1]] = NEXOBS < 1 ? -1 : NFREQ;
}
}
if (m >= 2)
{
if (val[l[0]] == 0.0 && val[l[1]] == 0.0)
{
p[l[0]] = -1;
p[l[1]] = -1;
}
else if (val[l[0]] != 0.0 && val[l[1]] == 0.0)
{
p[l[0]] = 1;
p[l[1]] = -1;
}
else if (val[l[0]] == 0.0 && val[l[1]] != 0.0)
{
p[l[0]] = -1;
p[l[1]] = 1;
}
else if (ind->pri[l[1]] > ind->pri[l[0]])
{
p[l[1]] = 1;
p[l[0]] = NEXOBS < 2 ? -1 : NFREQ + 1;
}
else
{
p[l[0]] = 1;
p[l[1]] = NEXOBS < 2 ? -1 : NFREQ + 1;
}
}
if (q >= 2)
{
if (val[r[0]] == 0.0 && val[r[1]] == 0.0)
{
p[r[0]] = -1;
p[r[1]] = -1;
}
else if (val[r[0]] != 0.0 && val[r[1]] == 0.0)
{
p[r[0]] = 2;
p[r[1]] = -1;
}
else if (val[r[0]] == 0.0 && val[r[1]] != 0.0)
{
p[r[0]] = -1;
p[r[1]] = 2;
}
else if (ind->pri[r[1]] > ind->pri[r[0]])
{
p[r[1]] = 2;
p[r[0]] = NEXOBS < 3 ? -1 : NFREQ + 2;
}
else
{
p[r[0]] = 2;
p[r[1]] = NEXOBS < 3 ? -1 : NFREQ + 2;
}
}
/* save observation data */
for (i = 0; i < ind->n; i++)
{
if (p[i] < 0 || (val[i] == 0.0 && lli[i] == 0))
continue;
switch (ind->type[i])
{
case 0:
obs->P[p[i]] = val[i];
obs->code[p[i]] = ind->code[i];
obs->qualP[p[i]] = std[i] > 0 ? std[i] : 1;
break;
case 1:
obs->L[p[i]] = val[i];
obs->LLI[p[i]] = lli[i];
obs->qualL[p[i]] = std[i] > 0 ? std[i] : 1;
break;
case 2:
obs->D[p[i]] = (float)val[i];
break;
case 3:
obs->SNR[p[i]] = (unsigned char)(val[i] / SNR_UNIT + 0.5);
break;
}
printf("obs: i=%d f=%d P=%10.3f L=%10.3f LLI=%d code=%d\n", i, p[i], obs->P[p[i]],
obs->L[p[i]], obs->LLI[p[i]], obs->code[p[i]]);
}
char time_str[64];
time2str(obs->time, time_str, 0);
printf("decode_obsdata: time=%s sat=%2d\n", time_str, obs->sat);
return 1;
}

18
src/decodeobs.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef DECODEOBS_H
#define DECODEOBS_H
#include "comtyp.h"
#include <stdio.h>
/* decode RINEX observation data file header ---------------------------------*/
void decode_obsh(FILE *fp, char *buff, double ver, int *tsys,
char tobs[][MAXOBSTYPE][4],obs_t* obs, nav_t *nav, sta_t *sta);
/* decode observation epoch --------------------------------------------------*/
int decode_obsepoch(FILE *fp, char *buff, double ver, gtime_t *time,
int *flag, int *sats);
/* decode observation data ---------------------------------------------------*/
int decode_obsdata(FILE *fp, char *buff, double ver, int mask,
sigind_t *index, obsd_t *obs);
#endif

14
src/init_val.c Normal file
View File

@ -0,0 +1,14 @@
#include "init_val.h"
void init_sta(sta_t *sta)
{
memset(sta,0,sizeof(sta_t));
/*int i;
for (i = 0; i < 3; i++){
sta->pos[i] = 0.0;
}
for (i = 0; i < 3; i++){
sta->del[i] = 0.0;
}
sta->hgt = 0.0;*/
return;
}

7
src/init_val.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef INIT_VAL_H
#define INIT_VAL_H
#include "comtyp.h"
void init_sta(sta_t *sta);
#endif

29
src/main.c Normal file
View File

@ -0,0 +1,29 @@
#include <stdio.h>
#include <stdlib.h>
#include "readobsnav.h"
#include "comtyp.h"
#include "option.h"
#include "init_val.h"
int main()
{
gtime_t ts = {0},te = {0};
double ti = 0;
char* infile[256];
char file0[] = "/home/ununtu/Downloads/PRIDE-PPPAR/data/TWTF00TWN_R_20233310000_01D_30S_MO/TWTF00TWN_R_20233310000_01D_30S_MO.rnx";
char file1[] = "/home/ununtu/Downloads/PRIDE-PPPAR/data/TWTF00TWN_R_20233310000_01D_30S_MO/brdm3310.23p";
infile[0] = &file0;
infile[1] = &file1;
int index=0;
int n = 2;
prcopt_t prcopt;
obs_t obs = {0};
nav_t nav = {0};
sta_t sta = {0};
readobsnav(ts, te, ti,infile,&index,n,&prcopt,&obs,&nav,&sta);
freeobsnav(&obs,&nav);
return 0;
}

151
src/obscode.c Normal file
View File

@ -0,0 +1,151 @@
#include "obscode.h"
#include "const.h"
void convcode(double ver, int sys, const char *str, char *type)
{
strcpy(type, " ");
if (!strcmp(str, "P1"))
{ /* ver.2.11 GPS L1PY,GLO L2P */
if (sys == SYS_GPS)
sprintf(type, "%c1W", 'C');
else if (sys == SYS_GLO)
sprintf(type, "%c1P", 'C');
}
else if (!strcmp(str, "P2"))
{ /* ver.2.11 GPS L2PY,GLO L2P */
if (sys == SYS_GPS)
sprintf(type, "%c2W", 'C');
else if (sys == SYS_GLO)
sprintf(type, "%c2P", 'C');
}
else if (!strcmp(str, "C1"))
{ /* ver.2.11 GPS L1C,GLO L1C/A */
if (ver >= 2.12)
; /* reject C1 for 2.12 */
else if (sys == SYS_GPS)
sprintf(type, "%c1C", 'C');
else if (sys == SYS_GLO)
sprintf(type, "%c1C", 'C');
else if (sys == SYS_GAL)
sprintf(type, "%c1X", 'C'); /* ver.2.12 */
else if (sys == SYS_QZS)
sprintf(type, "%c1C", 'C');
else if (sys == SYS_SBS)
sprintf(type, "%c1C", 'C');
}
else if (!strcmp(str, "C2"))
{
if (sys == SYS_GPS)
{
if (ver >= 2.12)
sprintf(type, "%c2W", 'C'); /* L2P(Y) */
else
sprintf(type, "%c2X", 'C'); /* L2C */
}
else if (sys == SYS_GLO)
sprintf(type, "%c2C", 'C');
else if (sys == SYS_QZS)
sprintf(type, "%c2X", 'C');
else if (sys == SYS_CMP)
sprintf(type, "%c2X", 'C'); /* ver.2.12 B1_2 */
}
else if (ver >= 2.12 && str[1] == 'A')
{ /* ver.2.12 L1C/A */
if (sys == SYS_GPS)
sprintf(type, "%c1C", str[0]);
else if (sys == SYS_GLO)
sprintf(type, "%c1C", str[0]);
else if (sys == SYS_QZS)
sprintf(type, "%c1C", str[0]);
else if (sys == SYS_SBS)
sprintf(type, "%c1C", str[0]);
}
else if (ver >= 2.12 && str[1] == 'B')
{ /* ver.2.12 GPS L1C */
if (sys == SYS_GPS)
sprintf(type, "%c1X", str[0]);
else if (sys == SYS_QZS)
sprintf(type, "%c1X", str[0]);
}
else if (ver >= 2.12 && str[1] == 'C')
{ /* ver.2.12 GPS L2C */
if (sys == SYS_GPS)
sprintf(type, "%c2X", str[0]);
else if (sys == SYS_QZS)
sprintf(type, "%c2X", str[0]);
}
else if (ver >= 2.12 && str[1] == 'D')
{ /* ver.2.12 GLO L2C/A */
if (sys == SYS_GLO)
sprintf(type, "%c2C", str[0]);
}
else if (ver >= 2.12 && str[1] == '1')
{ /* ver.2.12 GPS L1PY,GLO L1P */
if (sys == SYS_GPS)
sprintf(type, "%c1W", str[0]);
else if (sys == SYS_GLO)
sprintf(type, "%c1P", str[0]);
else if (sys == SYS_GAL)
sprintf(type, "%c1X", str[0]); /* tentative */
else if (sys == SYS_CMP)
sprintf(type, "%c2X", str[0]); /* extension */
}
else if (ver < 2.12 && str[1] == '1')
{
if (sys == SYS_GPS)
sprintf(type, "%c1C", str[0]);
else if (sys == SYS_GLO)
sprintf(type, "%c1C", str[0]);
else if (sys == SYS_GAL)
sprintf(type, "%c1X", str[0]); /* tentative */
else if (sys == SYS_QZS)
sprintf(type, "%c1C", str[0]);
else if (sys == SYS_SBS)
sprintf(type, "%c1C", str[0]);
}
else if (str[1] == '2')
{
if (sys == SYS_GPS)
sprintf(type, "%c2W", str[0]);
else if (sys == SYS_GLO)
sprintf(type, "%c2P", str[0]);
else if (sys == SYS_QZS)
sprintf(type, "%c2X", str[0]);
else if (sys == SYS_CMP)
sprintf(type, "%c2X", str[0]); /* ver.2.12 B1_2 */
}
else if (str[1] == '5')
{
if (sys == SYS_GPS)
sprintf(type, "%c5X", str[0]);
else if (sys == SYS_GAL)
sprintf(type, "%c5X", str[0]);
else if (sys == SYS_QZS)
sprintf(type, "%c5X", str[0]);
else if (sys == SYS_SBS)
sprintf(type, "%c5X", str[0]);
}
else if (str[1] == '6')
{
if (sys == SYS_GAL)
sprintf(type, "%c6X", str[0]);
else if (sys == SYS_QZS)
sprintf(type, "%c6X", str[0]);
else if (sys == SYS_CMP)
sprintf(type, "%c6X", str[0]); /* ver.2.12 B3 */
}
else if (str[1] == '7')
{
if (sys == SYS_GAL)
sprintf(type, "%c7X", str[0]);
else if (sys == SYS_CMP)
sprintf(type, "%c7X", str[0]); /* ver.2.12 B2b */
}
else if (str[1] == '8')
{
if (sys == SYS_GAL)
sprintf(type, "%c8X", str[0]);
}
printf("convcode: ver=%.2f sys=%2d type= %s -> %s\n", ver, sys, str, type);
}

7
src/obscode.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef OBSCODE_H
#define OBSCODE_H
/* convert RINEX obs-type ver.2 -> ver.3 -------------------------------------*/
void convcode(double ver, int sys, const char *str, char *type);
#endif

78
src/option.h Normal file
View File

@ -0,0 +1,78 @@
#ifndef OPTION_H
#define OPTION_H
#include "const.h"
#include "comtyp.h"
#include <stdbool.h>
typedef struct
{
int mode; // positioning mode (PMODE_???)
int soltype; // solution type (0:forward,1:backward,2:combined)
int nf; // number of frequencies (1:L1,2:L1+L2,3:L1+L2+L5)
int navsys; // navigation system
double elmin; // elevation mask angle (rad)
int sateph; // satellite ephemeris/clock (EPHOPT_???)
int ionoopt; // ionosphere option (IONOOPT_???)
int tropopt; // troposphere option (TROPOPT_???)
int niter; // number of filter iteration
double maxinno; // reject threshold of innovation (m)
double maxgdop; // reject threshold of gdop
int exsats[MAXSAT]; // excluded satellites (1:excluded,2:included)
char rnxopt[2][256]; // rinex options {rover,base}
int posopt[6]; // positioning options
bool lsa; // SA data (before 2000/123)
}prcopt_t;
typedef struct
{
int posf; // solution format (SOLF_???)
int times; // time system (TIMES_???)
int timef; // time format (0:sssss.s,1:yyyy/mm/dd hh:mm:ss.s)
int timeu; // time digits under decimal point
int degf; // latitude/longitude format (0:ddd.ddd,1:ddd mm ss)
int outhead; // output header (0:no,1:yes)
int outopt; // output processing options (0:no,1:yes)
int outvel; // output velocity options (0:no,1:yes)
int datum; // datum (0:WGS84,1:Tokyo)
int height; // height (0:ellipsoidal,1:geodetic)
int geoid; // geoid model (0:EGM96,1:JGD2000)
int solstatic; // solution of static mode (0:all,1:single)
int sstat; // solution statistics level (0:off,1:states,2:residuals)
int trace; // debug trace level (0:off,1-5:debug)
int issingle; // single solution (0:no,1:yes)
double nmeaintv[2]; // nmea output interval (s) ( .lt. 0:no,0:all)
// nmeaintv(0):gprmc,gpgga,nmeaintv(1):gpgsv
char sep[64]; // field separator
char prog[64]; // program name
double maxsolstd; // max std-dev for solution output (m) (0:all)
}solopt_t;
typedef struct
{
gtime_t ts,te; // time start/end
double tint; // time interval (s)
double ttol; // time tolerance (s)
double tunit; // time unit for multiple-session (s)
double rnxver; // RINEX version
int navsys; // navigation system
int obstype; // observation type
int freqtype; // frequency type
char mask[7][64]; // code mask {GPS,GLO,GAL,QZS,SBS,CMP,IRN}
char staid[32]; // station id for rinex file name
char prog[32]; // program
char runby[32]; // run-by
char marker[32]; // marker name
char markerno[32]; // marker number
char markertype[32]; // marker type (ver.3)
char name[2][32]; // observer/agency
char rec[3][32]; // receiver #/type/vers
char ant[3][32]; // antenna #/type
int exsats[MAXSAT]; // excluded satellites
gtime_t tstart; // first obs time
gtime_t tend; // last obs time
char tobs[7][MAXOBSTYPE][4]; // obs types {GPS,GLO,GAL,QZS,SBS,CMP,IRN}
int nobs[7]; // number of obs types {GPS,GLO,GAL,QZS,SBS,CMP,IRN}
}rnxopt_t;
#endif

1079
src/readobsnav.c Normal file

File diff suppressed because it is too large Load Diff

70
src/readobsnav.h Normal file
View File

@ -0,0 +1,70 @@
#ifndef READOBSNAV_H
#define READOBSNAV_H
#include "comtyp.h"
#include "option.h"
#include "const.h"
// Read obs and nav data -----------------------------------------------------
bool readobsnav(gtime_t ts, gtime_t te, double ti,const char** infile,const int* index,int n,
const prcopt_t* prcopt,obs_t* obs,nav_t* nav,sta_t* sta);
// read rinex obs and nav files ----------------------------------------------
//return -1,0: error, 1-normal
int readrnxt(const char *filepath,int rcv,gtime_t ts,gtime_t te,double ti,const char* opt,
obs_t* obs,nav_t* nav,sta_t* sta);
//read rinex file --------------------------------------------
//return -1,0: error, 1-normal
int readrnxfile(const char *filepath,gtime_t ts,gtime_t te,double ti,const char* opt,
int flag,int index,char* type,obs_t* obs,nav_t* nav,sta_t* sta);
// read rinex file -----------------------------------------------------------
// 0-error, 1-normal
int readrnxfp(FILE* fp,gtime_t ts,gtime_t te,double ti,const char* opt,
int flag,int index,char* type,obs_t* obs,nav_t* nav,sta_t* sta);
/* read RINEX file header ----------------------------------------------------*/
// 0-error, 1-normal
int readrnxh(FILE *fp, double *ver, char *type, int *sys, int *tsys,
char tobs[][MAXOBSTYPE][4],obs_t* obs, nav_t *nav, sta_t *sta);
/* read RINEX observation data -----------------------------------------------*/
int readrnxobs(FILE *fp, gtime_t ts, gtime_t te, double ti,
const char *opt, int rcv, double ver, int *tsys,
char tobs[][MAXOBSTYPE][4], obs_t *obs, sta_t *sta);
/* read RINEX observation data body ------------------------------------------*/
int readrnxobsb(FILE *fp, const char *opt, double ver, int *tsys,
char tobs[][MAXOBSTYPE][4], int *flag, obsd_t *data,
sta_t *sta);
/* save cycle slips ----------------------------------------------------------*/
void saveslips(unsigned char slips[][NFREQ + NEXOBS], obsd_t *data);
/* screen by time --------------------------------------------------------------
* screening by time start, time end, and time interval
* args : gtime_t time I time
* gtime_t ts I time start (ts.time==0:no screening by ts)
* gtime_t te I time end (te.time==0:no screening by te)
* double tint I time interval (s) (0.0:no screen by tint)
* return : 1:on condition, 0:not on condition
*-----------------------------------------------------------------------------*/
int screent(gtime_t time, gtime_t ts, gtime_t te, double tint);
/* restore cycle slips -------------------------------------------------------*/
void restoreslips(unsigned char slips[][NFREQ + NEXOBS], obsd_t *data);
/* add observation data ------------------------------------------------------*/
int addobsdata(obs_t *obs, const obsd_t *data);
/* read RINEX navigation data ------------------------------------------------*/
int readrnxnav(FILE *fp, const char *opt, double ver, int sys, nav_t *nav);
/* read RINEX navigation data body -------------------------------------------*/
int readrnxnavb(FILE *fp, const char *opt, double ver, int sys,
int *type, eph_t *eph, geph_t *geph, seph_t *seph);
void freeobsnav(obs_t *obs, nav_t* nav);
#endif

158
src/satellite.c Normal file
View File

@ -0,0 +1,158 @@
#include "satellite.h"
#include "const.h"
extern int satid2no(const char *id)
{
int sys, prn;
char code;
if (sscanf(id, "%d", &prn) == 1)
{
if (MINPRNGPS <= prn && prn <= MAXPRNGPS)
sys = SYS_GPS;
else if (MINPRNSBS <= prn && prn <= MAXPRNSBS)
sys = SYS_SBS;
else if (MINPRNQZS <= prn && prn <= MAXPRNQZS)
sys = SYS_QZS;
else
return 0;
return satno(sys, prn);
}
if (sscanf(id, "%c%d", &code, &prn) < 2)
return 0;
switch (code)
{
case 'G':
sys = SYS_GPS;
prn += MINPRNGPS - 1;
break;
case 'R':
sys = SYS_GLO;
prn += MINPRNGLO - 1;
break;
case 'E':
sys = SYS_GAL;
prn += MINPRNGAL - 1;
break;
case 'J':
sys = SYS_QZS;
prn += MINPRNQZS - 1;
break;
case 'C':
sys = SYS_CMP;
prn += MINPRNCMP - 1;
break;
case 'I':
sys = SYS_IRN;
prn += MINPRNIRN - 1;
break;
case 'L':
sys = SYS_LEO;
prn += MINPRNLEO - 1;
break;
case 'S':
sys = SYS_SBS;
prn += 100;
break;
default:
return 0;
}
return satno(sys, prn);
}
int satno(int sys, int prn)
{
if (prn <= 0)
return 0;
switch (sys)
{
case SYS_GPS:
if (prn < MINPRNGPS || MAXPRNGPS < prn)
return 0;
return prn - MINPRNGPS + 1;
case SYS_GLO:
if (prn < MINPRNGLO || MAXPRNGLO < prn)
return 0;
return NSATGPS + prn - MINPRNGLO + 1;
case SYS_GAL:
if (prn < MINPRNGAL || MAXPRNGAL < prn)
return 0;
return NSATGPS + NSATGLO + prn - MINPRNGAL + 1;
case SYS_QZS:
if (prn < MINPRNQZS || MAXPRNQZS < prn)
return 0;
return NSATGPS + NSATGLO + NSATGAL + prn - MINPRNQZS + 1;
case SYS_CMP:
if (prn < MINPRNCMP || MAXPRNCMP < prn)
return 0;
return NSATGPS + NSATGLO + NSATGAL + NSATQZS + prn - MINPRNCMP + 1;
case SYS_IRN:
if (prn < MINPRNIRN || MAXPRNIRN < prn)
return 0;
return NSATGPS + NSATGLO + NSATGAL + NSATQZS + NSATCMP + prn - MINPRNIRN + 1;
case SYS_LEO:
if (prn < MINPRNLEO || MAXPRNLEO < prn)
return 0;
return NSATGPS + NSATGLO + NSATGAL + NSATQZS + NSATCMP + NSATIRN +
prn - MINPRNLEO + 1;
case SYS_SBS:
if (prn < MINPRNSBS || MAXPRNSBS < prn)
return 0;
return NSATGPS + NSATGLO + NSATGAL + NSATQZS + NSATCMP + NSATIRN + NSATLEO +
prn - MINPRNSBS + 1;
}
return 0;
}
int satsys(int sat, int *prn)
{
int sys = SYS_NONE;
if (sat <= 0 || MAXSAT < sat)
sat = 0;
else if (sat <= NSATGPS)
{
sys = SYS_GPS;
sat += MINPRNGPS - 1;
}
else if ((sat -= NSATGPS) <= NSATGLO)
{
sys = SYS_GLO;
sat += MINPRNGLO - 1;
}
else if ((sat -= NSATGLO) <= NSATGAL)
{
sys = SYS_GAL;
sat += MINPRNGAL - 1;
}
else if ((sat -= NSATGAL) <= NSATQZS)
{
sys = SYS_QZS;
sat += MINPRNQZS - 1;
}
else if ((sat -= NSATQZS) <= NSATCMP)
{
sys = SYS_CMP;
sat += MINPRNCMP - 1;
}
else if ((sat -= NSATCMP) <= NSATIRN)
{
sys = SYS_IRN;
sat += MINPRNIRN - 1;
}
else if ((sat -= NSATIRN) <= NSATLEO)
{
sys = SYS_LEO;
sat += MINPRNLEO - 1;
}
else if ((sat -= NSATLEO) <= NSATSBS)
{
sys = SYS_SBS;
sat += MINPRNSBS - 1;
}
else
sat = 0;
if (prn)
*prn = sat;
return sys;
}

28
src/satellite.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef SATELLITE_H
#define SATELLITE_H
/* satellite id to satellite number --------------------------------------------
* convert satellite id to satellite number
* args : char *id I satellite id (nn,Gnn,Rnn,Enn,Jnn,Cnn,Inn or Snn)
* return : satellite number (0: error)
* notes : 120-142 and 193-199 are also recognized as sbas and qzss
*-----------------------------------------------------------------------------*/
int satid2no(const char *id);
/* satellite system+prn/slot number to satellite number ------------------------
* convert satellite system+prn/slot number to satellite number
* args : int sys I satellite system (SYS_GPS,SYS_GLO,...)
* int prn I satellite prn/slot number
* return : satellite number (0:error)
*-----------------------------------------------------------------------------*/
int satno(int sys, int prn);
/* satellite number to satellite system ----------------------------------------
* convert satellite number to satellite system
* args : int sat I satellite number (1-MAXSAT)
* int *prn IO satellite prn/slot number (NULL: no output)
* return : satellite system (SYS_GPS,SYS_GLO,...)
*-----------------------------------------------------------------------------*/
int satsys(int sat, int *prn);
#endif

76
src/str.c Normal file
View File

@ -0,0 +1,76 @@
#include <math.h>
#include "str.h"
#include "timeconvert.h"
void setstr(char *dst, const char *src, int n)
{
char *p = dst;
const char *q = src;
while (*q && q < src + n)
{
*p++ = *q++;
}
*p-- = '\0';
while (p >= dst && *p == ' ')
{
*p-- = '\0';
}
return;
}
double str2num(const char *s, int i, int n)
{
double value;
char str[256], *p = str;
if (i < 0 || (int)strlen(s) < i || (int)sizeof(str) - 1 < n)
return 0.0;
for (s += i; *s && --n >= 0; s++)
*p++ = *s == 'd' || *s == 'D' ? 'E' : *s;
*p = '\0';
return sscanf(str, "%lf", &value) == 1 ? value : 0.0;
}
int str2time(const char *s, int i, int n, gtime_t *t)
{
double ep[6];
char str[256], *p = str;
if (i < 0 || (int)strlen(s) < i || (int)sizeof(str) - 1 < i)
return -1;
for (s += i; *s && --n >= 0;)
*p++ = *s++;
*p = '\0';
if (sscanf(str, "%lf %lf %lf %lf %lf %lf", ep, ep + 1, ep + 2, ep + 3, ep + 4, ep + 5) < 6)
return -1;
if (ep[0] < 100.0)
ep[0] += ep[0] < 80.0 ? 2000.0 : 1900.0;
*t = epoch2time(ep);
return 0;
}
/* time to string --------------------------------------------------------------
* convert gtime_t struct to string
* args : gtime_t t I gtime_t struct
* char *s O string ("yyyy/mm/dd hh:mm:ss.ssss")
* int n I number of decimals
* return : none
*-----------------------------------------------------------------------------*/
void time2str(gtime_t t, char *s, int n)
{
double ep[6];
if (n < 0)
n = 0;
else if (n > 12)
n = 12;
if (1.0 - t.sec < 0.5 / pow(10.0, n))
{
t.time++;
t.sec = 0.0;
};
time2epoch(t, ep);
sprintf(s, "%04.0f/%02.0f/%02.0f %02.0f:%02.0f:%0*.*f", ep[0], ep[1], ep[2],
ep[3], ep[4], n <= 0 ? 2 : n + 3, n <= 0 ? 0 : n, ep[5]);
}

34
src/str.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef STR_H
#define STR_H
#include "comtyp.h"
//set string without tail space
void setstr(char *dst, const char *src, int n);
/* string to number ------------------------------------------------------------
* convert substring in string to number
* args : char *s I string ("... nnn.nnn ...")
* int i,n I substring position and width
* return : converted number (0.0:error)
*-----------------------------------------------------------------------------*/
double str2num(const char *s, int i, int n);
/* string to time --------------------------------------------------------------
* convert substring in string to gtime_t struct
* args : char *s I string ("... yyyy mm dd hh mm ss ...")
* int i,n I substring position and width
* gtime_t *t O gtime_t struct
* return : status (0:ok,0>:error)
*-----------------------------------------------------------------------------*/
int str2time(const char *s, int i, int n, gtime_t *t);
/* time to string --------------------------------------------------------------
* convert gtime_t struct to string
* args : gtime_t t I gtime_t struct
* char *s O string ("yyyy/mm/dd hh:mm:ss.ssss")
* int n I number of decimals
* return : none
*-----------------------------------------------------------------------------*/
void time2str(gtime_t t, char *s, int n);
#endif

132
src/timeconvert.c Normal file
View File

@ -0,0 +1,132 @@
#include <time.h>
#include "timeconvert.h"
gtime_t epoch2time(const double *ep)
{
const int doy[] = {1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
gtime_t time = {0};
int days, sec, year = (int)ep[0], mon = (int)ep[1], day = (int)ep[2];
if (year < 1970 || 2099 < year || mon < 1 || 12 < mon)
return time;
/* leap year if year%4==0 in 1901-2099 */
days = (year - 1970) * 365 + (year - 1969) / 4 + doy[mon - 1] + day - 2 + (year % 4 == 0 && mon >= 3 ? 1 : 0);
sec = (int)floor(ep[5]);
time.time = (time_t)days * 86400 + (int)ep[3] * 3600 + (int)ep[4] * 60 + sec;
time.sec = ep[5] - sec;
return time;
}
void time2epoch(gtime_t t, double *ep)
{
const int mday[] = {/* # of days in a month */
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int days, sec, mon, day;
/* leap year if year%4==0 in 1901-2099 */
days = (int)(t.time / 86400);
sec = (int)(t.time - (time_t)days * 86400);
for (day = days % 1461, mon = 0; mon < 48; mon++)
{
if (day >= mday[mon])
day -= mday[mon];
else
break;
}
ep[0] = 1970 + days / 1461 * 4 + mon / 12;
ep[1] = mon % 12 + 1;
ep[2] = day + 1;
ep[3] = sec / 3600;
ep[4] = sec % 3600 / 60;
ep[5] = sec % 60 + t.sec;
}
gtime_t utc2gpst(gtime_t t)
{
int i;
for (i = 0; leaps[i][0] > 0; i++)
{
if (timediff(t, epoch2time(leaps[i])) >= 0.0)
return timeadd(t, -leaps[i][6]);
}
return t;
}
double timediff(gtime_t t1, gtime_t t2)
{
return difftime(t1.time, t2.time) + t1.sec - t2.sec;
}
gtime_t timeadd(gtime_t t, double sec)
{
double tt;
t.sec += sec;
tt = floor(t.sec);
t.time += (int)tt;
t.sec -= tt;
return t;
}
double time2gpst(gtime_t t, int *week)
{
gtime_t t0 = epoch2time(gpst0);
time_t sec = t.time - t0.time;
int w = (int)(sec / (86400 * 7));
if (week)
*week = w;
return (double)(sec - (double)w * 86400 * 7) + t.sec;
}
gtime_t gpst2time(int week, double sec)
{
gtime_t t = epoch2time(gpst0);
if (sec < -1E9 || 1E9 < sec)
sec = 0.0;
t.time += (time_t)86400 * 7 * week + (int)sec;
t.sec = sec - (int)sec;
return t;
}
/* adjust time considering week handover -------------------------------------*/
gtime_t adjday(gtime_t t, gtime_t t0)
{
double tt = timediff(t, t0);
if (tt < -43200.0)
return timeadd(t, 86400.0);
if (tt > 43200.0)
return timeadd(t, -86400.0);
return t;
}
gtime_t adjweek(gtime_t t, gtime_t t0)
{
double tt = timediff(t, t0);
if (tt < -302400.0)
return timeadd(t, 604800.0);
if (tt > 302400.0)
return timeadd(t, -604800.0);
return t;
}
gtime_t bdt2time(int week, double sec)
{
gtime_t t = epoch2time(bdt0);
if (sec < -1E9 || 1E9 < sec)
sec = 0.0;
t.time += (time_t)86400 * 7 * week + (int)sec;
t.sec = sec - (int)sec;
return t;
}
gtime_t bdt2gpst(gtime_t t)
{
return timeadd(t, 14.0);
}

84
src/timeconvert.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef TIME_H
#define TIME_H
#include "comtyp.h"
/* convert calendar day/time to time -------------------------------------------
* convert calendar day/time to gtime_t struct
* args : double *ep I day/time {year,month,day,hour,min,sec}
* return : gtime_t struct
* notes : proper in 1970-2037 or 1970-2099 (64bit time_t)
*-----------------------------------------------------------------------------*/
gtime_t epoch2time(const double *ep);
/* time to calendar day/time ---------------------------------------------------
* convert gtime_t struct to calendar day/time
* args : gtime_t t I gtime_t struct
* double *ep O day/time {year,month,day,hour,min,sec}
* return : none
* notes : proper in 1970-2037 or 1970-2099 (64bit time_t)
*-----------------------------------------------------------------------------*/
void time2epoch(gtime_t t, double *ep);
/* utc to gpstime --------------------------------------------------------------
* convert utc to gpstime considering leap seconds
* args : gtime_t t I time expressed in utc
* return : time expressed in gpstime
* notes : ignore slight time offset under 100 ns
*-----------------------------------------------------------------------------*/
gtime_t utc2gpst(gtime_t t);
/* time difference -------------------------------------------------------------
* difference between gtime_t structs
* args : gtime_t t1,t2 I gtime_t structs
* return : time difference (t1-t2) (s)
*-----------------------------------------------------------------------------*/
double timediff(gtime_t t1, gtime_t t2);
/* add time --------------------------------------------------------------------
* add time to gtime_t struct
* args : gtime_t t I gtime_t struct
* double sec I time to add (s)
* return : gtime_t struct (t+sec)
*-----------------------------------------------------------------------------*/
gtime_t timeadd(gtime_t t, double sec);
/* time to gps time ------------------------------------------------------------
* convert gtime_t struct to week and tow in gps time
* args : gtime_t t I gtime_t struct
* int *week IO week number in gps time (NULL: no output)
* return : time of week in gps time (s)
*-----------------------------------------------------------------------------*/
double time2gpst(gtime_t t, int *week);
/* gps time to time ------------------------------------------------------------
* convert week and tow in gps time to gtime_t struct
* args : int week I week number in gps time
* double sec I time of week in gps time (s)
* return : gtime_t struct
*-----------------------------------------------------------------------------*/
gtime_t gpst2time(int week, double sec);
/* adjust time considering week handover -------------------------------------*/
gtime_t adjday(gtime_t t, gtime_t t0);
/* adjust time considering week handover -------------------------------------*/
gtime_t adjweek(gtime_t t, gtime_t t0);
/* beidou time (bdt) to time ---------------------------------------------------
* convert week and tow in beidou time (bdt) to gtime_t struct
* args : int week I week number in bdt
* double sec I time of week in bdt (s)
* return : gtime_t struct
*-----------------------------------------------------------------------------*/
gtime_t bdt2time(int week, double sec);
/* bdt to gpstime --------------------------------------------------------------
* convert bdt (beidou navigation satellite system time) to gpstime
* args : gtime_t t I time expressed in bdt
* return : time expressed in gpstime
* notes : see gpst2bdt()
*-----------------------------------------------------------------------------*/
gtime_t bdt2gpst(gtime_t t);
#endif