对于初学者,可能面对全英文的程序注释可能比较吃力,这里把笔者之前做二次开发时翻译的中文版本的头文件贴出来,其中缺少部分数据流函数,但是基本不会影响我们的学习。RTKLIB使用的结构体和函数均在头文件中有详细总结,大家可以根据这个头文件理清楚整个项目都有那些函数,有一个大概的把握。

/*——————————————————————————
* rtklib.h : RTKLIB 常量、类型和函数原型
*
*
* 选项 : -DENAGLO 启用 GLONASS
* : -DENAGAL 启用 Galileo
* : -DENAQZS 启用 QZSS
* : -DENACMP 启用 BeiDou
* : -DENAIRN 启用 IRNSS
* : -DNFREQ=n 设置观测代码/频率的数量
* : -DNEXOBS=n 设置扩展观测代码的数量
* : -DMAXOBS=n 设置一个历元中的最大观测数据数量
* : -DWIN32 使用 WIN32 API
* : -DWIN_DLL 生成 Windows DLL 库
*—————————————————————————–*/
#ifndef RTKLIB_H
#define RTKLIB_H
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <stdint.h>
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#else
#include <pthread.h>
#include <sys/select.h>
#endif
#ifdef __cplusplus
extern “C” {
#endif

#ifdef WIN_DLL
#define EXPORT __declspec(dllexport) /* for Windows DLL */
#else
#define EXPORT
#endif

#define ENAGLO
#define ENAGAL
#define ENACMP
#define ENAQZS
#define ENAIRN

/* 常量 ————————————————————————-*/

#define PI 3.1415926535897932 /* π */
#define D2R (PI/180.0) /* 角度转弧度 */
#define R2D (180.0/PI) /* 弧度转角度 */
#define CLIGHT 299792458.0 /* 光速 (米/秒) */
#define SC2RAD 3.1415926535898 /* 半圆转弧度 (IS-GPS) */
#define AU 149597870691.0 /* 1 天文单位 (米) */
#define AS2R (D2R/3600.0) /* 角秒转弧度 */

#define OMGE 7.2921151467E-5 /* 地球角速度 (IS-GPS) (弧度/秒) */

#define RE_WGS84 6378137.0 /* 地球长半轴 (WGS84) (米) */
#define FE_WGS84 (1.0/298.257223563) /* 地球扁率 (WGS84) */

#define HION 350000.0 /* 电离层高度 (米) */

#define MAXFREQ 7 /* 最大频率数量 */

#define FREQ1 1.57542E9 /* L1/E1/B1C 频率 (赫兹) */
#define FREQ2 1.22760E9 /* L2 频率 (赫兹) */
#define FREQ5 1.17645E9 /* L5/E5a/B2a 频率 (赫兹) */
#define FREQ6 1.27875E9 /* E6/L6 频率 (赫兹) */
#define FREQ7 1.20714E9 /* E5b 频率 (赫兹) */
#define FREQ8 1.191795E9 /* E5a+b 频率 (赫兹) */
#define FREQ9 2.492028E9 /* S 频率 (赫兹) */
#define FREQ1_GLO 1.60200E9 /* GLONASS G1 基础频率 (赫兹) */
#define DFRQ1_GLO 0.56250E6 /* GLONASS G1 偏移频率 (赫兹/编号) */
#define FREQ2_GLO 1.24600E9 /* GLONASS G2 基础频率 (赫兹) */
#define DFRQ2_GLO 0.43750E6 /* GLONASS G2 偏移频率 (赫兹/编号) */
#define FREQ3_GLO 1.202025E9 /* GLONASS G3 频率 (赫兹) */
#define FREQ1a_GLO 1.600995E9 /* GLONASS G1a 频率 (赫兹) */
#define FREQ2a_GLO 1.248060E9 /* GLONASS G2a 频率 (赫兹) */
#define FREQ1_CMP 1.561098E9 /* 北斗 B1I 频率 (赫兹) */
#define FREQ2_CMP 1.20714E9 /* 北斗 B2I/B2b 频率 (赫兹) */
#define FREQ3_CMP 1.26852E9 /* 北斗 B3 频率 (赫兹) */

#define EFACT_GPS 1.0 /* 误差因子: GPS */
#define EFACT_GLO 1.5 /* 误差因子: GLONASS */
#define EFACT_GAL 1.0 /* 误差因子: Galileo */
#define EFACT_QZS 1.0 /* 误差因子: QZSS */
#define EFACT_CMP 1.0 /* 误差因子: 北斗 */
#define EFACT_IRN 1.5 /* 误差因子: IRNSS */
#define EFACT_SBS 3.0 /* 误差因子: SBAS */

#define SYS_NONE 0x00 /* 导航系统:无 */
#define SYS_GPS 0x01 /* 导航系统:GPS */
#define SYS_SBS 0x02 /* 导航系统:SBAS */
#define SYS_GLO 0x04 /* 导航系统:GLONASS */
#define SYS_GAL 0x08 /* 导航系统:Galileo */
#define SYS_QZS 0x10 /* 导航系统:QZSS */
#define SYS_CMP 0x20 /* 导航系统:北斗 */
#define SYS_IRN 0x40 /* 导航系统:IRNS */
#define SYS_LEO 0x80 /* 导航系统:LEO */
#define SYS_ALL 0xFF /* 导航系统:所有 */

#define TSYS_GPS 0 /* 时间系统: GPS 时间 */
#define TSYS_UTC 1 /* 时间系统: UTC 时间 */
#define TSYS_GLO 2 /* 时间系统: GLONASS 时间 */
#define TSYS_GAL 3 /* 时间系统: Galileo 时间 */
#define TSYS_QZS 4 /* 时间系统: QZSS 时间 */
#define TSYS_CMP 5 /* 时间系统: 北斗 时间 */
#define TSYS_IRN 6 /* 时间系统: IRNSS 时间 */

#define NFREQ 5 /* 载波频率数量 */

#define NFREQGLO 2 /* GLONASS 的载波频率数量 */

#ifndef NEXOBS
#define NEXOBS 0 /* 扩展观测码数量 */
#endif

#define SNR_UNIT 0.001 /* 信噪比单位 (dBHz) */

#define MINPRNGPS 1 /* GPS 卫星最小 PRN 号 */
#define MAXPRNGPS 32 /* GPS 卫星最大 PRN 号 */
#define NSATGPS (MAXPRNGPS-MINPRNGPS+1) /* GPS 卫星数量 */
#define NSYSGPS 1 /* GPS 系统数量 */

#ifdef ENAGLO
#define MINPRNGLO 1 /* GLONASS 的最小卫星槽号 */
#define MAXPRNGLO 27 /* GLONASS 的最大卫星槽号 */
#define NSATGLO (MAXPRNGLO-MINPRNGLO+1) /* GLONASS 的卫星数量 */
#define NSYSGLO 1
#else
#define MINPRNGLO 0
#define MAXPRNGLO 0
#define NSATGLO 0
#define NSYSGLO 0
#endif

#ifdef ENAGAL
#define MINPRNGAL 1 /* Galileo 的最小卫星 PRN 号 */
#define MAXPRNGAL 36 /* Galileo 的最大卫星 PRN 号 */
#define NSATGAL (MAXPRNGAL-MINPRNGAL+1) /* Galileo 的卫星数量 */
#define NSYSGAL 1
#else
#define MINPRNGAL 0
#define MAXPRNGAL 0
#define NSATGAL 0
#define NSYSGAL 0
#endif

#ifdef ENAQZS
#define MINPRNQZS 193 /* QZSS 的最小卫星 PRN 号 */
#define MAXPRNQZS 202 /* QZSS 的最大卫星 PRN 号 */
#define MINPRNQZS_S 183 /* QZSS L1S 的最小卫星 PRN 号 */
#define MAXPRNQZS_S 191 /* QZSS L1S 的最大卫星 PRN 号 */
#define NSATQZS (MAXPRNQZS-MINPRNQZS+1) /* QZSS 的卫星数量 */
#define NSYSQZS 1
#else
#define MINPRNQZS 0
#define MAXPRNQZS 0
#define MINPRNQZS_S 0
#define MAXPRNQZS_S 0
#define NSATQZS 0
#define NSYSQZS 0
#endif

#ifdef ENACMP
#define MINPRNCMP 1 /* 北斗 的最小卫星号 */
#define MAXPRNCMP 63 /* 北斗 的最大卫星号 */
#define NSATCMP (MAXPRNCMP-MINPRNCMP+1) /* 北斗 的卫星数量 */
#define NSYSCMP 1
#else
#define MINPRNCMP 0
#define MAXPRNCMP 0
#define NSATCMP 0
#define NSYSCMP 0
#endif

#ifdef ENAIRN
#define MINPRNIRN 1 /* IRNSS 的最小卫星号 */
#define MAXPRNIRN 14 /* IRNSS 的最大卫星号 */
#define NSATIRN (MAXPRNIRN-MINPRNIRN+1) /* IRNSS 的卫星数量 */
#define NSYSIRN 1
#else
#define MINPRNIRN 0
#define MAXPRNIRN 0
#define NSATIRN 0
#define NSYSIRN 0
#endif

#ifdef ENALEO
#define MINPRNLEO 1 /* LEO 的最小卫星号 */
#define MAXPRNLEO 10 /* LEO 的最大卫星号 */
#define NSATLEO (MAXPRNLEO-MINPRNLEO+1) /* LEO 的卫星数量 */
#define NSYSLEO 1
#else
#define MINPRNLEO 0
#define MAXPRNLEO 0
#define NSATLEO 0
#define NSYSLEO 0
#endif

#define NSYS (NSYSGPS+NSYSGLO+NSYSGAL+NSYSQZS+NSYSCMP+NSYSIRN+NSYSLEO) /* 系统数量 */

#define MINPRNSBS 120 /* SBAS 的最小卫星 PRN 号 */
#define MAXPRNSBS 158 /* SBAS 的最大卫星 PRN 号 */
#define NSATSBS (MAXPRNSBS-MINPRNSBS+1) /* SBAS 的卫星数量 */

#define MAXSAT (NSATGPS+NSATGLO+NSATGAL+NSATQZS+NSATCMP+NSATIRN+NSATSBS+NSATLEO)
/* 最大卫星数量(1 到 MAXSAT) */
#define MAXSTA 255

#ifndef MAXOBS
#define MAXOBS 96 /* 一个历元的最大观测数量 */
#endif

#define MAXRCV 64 /* 最大接收机数量(1 到 MAXRCV) */
#define MAXOBSTYPE 64 /* RINEX 中最大观测类型数量 */

#ifdef OBS_100HZ
#define DTTOL 0.005 /* 时间差异容差(秒) */
#else
#define DTTOL 0.025 /* 时间差异容差(秒) */
#endif

#define MAXDTOE 7200.0 /* 到 GPS Toe 的最大时间差(秒) */
#define MAXDTOE_QZS 7200.0 /* 到 QZSS Toe 的最大时间差(秒) */
#define MAXDTOE_GAL 14400.0 /* 到 Galileo Toe 的最大时间差(秒) */
#define MAXDTOE_CMP 21600.0 /* 到 北斗 Toe 的最大时间差(秒) */
#define MAXDTOE_GLO 1800.0 /* 到 GLONASS Toe 的最大时间差(秒) */
#define MAXDTOE_IRN 7200.0 /* 到 IRNSS Toe 的最大时间差(秒) */
#define MAXDTOE_SBS 360.0 /* 到 SBAS Toe 的最大时间差(秒) */
#define MAXDTOE_S 86400.0 /* 到其他 Toe 的最大时间差(秒) */
#define MAXGDOP 300.0 /* 最大 GDOP */

#define INT_SWAP_TRAC 86400.0 /* 追踪文件的交换间隔(秒) */
#define INT_SWAP_STAT 86400.0 /* 解决状态文件的交换间隔(秒) */

#define MAXEXFILE 1024 /* 最大扩展文件数 */
#define MAXSBSAGEF 30.0 /* SBAS快速修正的最大年龄 (秒) */
#define MAXSBSAGEL 1800.0 /* SBAS长期修正的最大年龄 (秒) */
#define MAXSBSURA 8 /* SBAS卫星的最大URA */
#define MAXBAND 10 /* IGP的最大SBAS频段 */
#define MAXNIGP 201 /* SBAS频段中IGP的最大数量 */
#define MAXNGEO 4 /* GEO卫星的最大数量 */
#define MAXCOMMENT 100 /* RINEX注释的最大数量 */
#define MAXSTRPATH 1024 /* 流路径的最大长度 */
#define MAXSTRMSG 1024 /* 流消息的最大长度 */
#define MAXSTRRTK 8 /* RTK服务器中流的最大数量 */
#define MAXSBSMSG 32 /* RTK服务器中SBAS消息的最大数量 */
#define MAXSOLMSG 8191 /* 解决方案消息的最大长度 */
#define MAXRAWLEN 16384 /* 接收器原始消息的最大长度 */
#define MAXERRMSG 4096 /* 错误/警告消息的最大长度 */
#define MAXANT 64 /* 站名/天线类型的最大长度 */
#define MAXSOLBUF 256 /* 解决方案缓冲区的最大数量 */
#define MAXOBSBUF 128 /* 观测数据缓冲区的最大数量 */
#define MAXNRPOS 16 /* 参考位置的最大数量 */
#define MAXLEAPS 64 /* 闰秒表的最大数量 */
#define MAXGISLAYER 32 /* GIS数据层的最大数量 */
#define MAXRCVCMD 4096 /* 接收器命令的最大长度 */

#define RNX2VER 2.10 /* RINEX版本2的默认输出版本 */
#define RNX3VER 3.00 /* RINEX版本3的默认输出版本 */

#define OBSTYPE_PR 0x01 /* 观测类型:伪距 */
#define OBSTYPE_CP 0x02 /* 观测类型:载波相位 */
#define OBSTYPE_DOP 0x04 /* 观测类型:多普勒频率 */
#define OBSTYPE_SNR 0x08 /* 观测类型:信噪比 */
#define OBSTYPE_ALL 0xFF /* 观测类型:全部 */

#define FREQTYPE_L1 0x01 /* 频率类型:L1/E1/B1 */
#define FREQTYPE_L2 0x02 /* 频率类型:L2/E5b/B2 */
#define FREQTYPE_L3 0x04 /* 频率类型:L5/E5a/L3 */
#define FREQTYPE_L4 0x08 /* 频率类型:L6/E6/B3 */
#define FREQTYPE_L5 0x10 /* 频率类型:E5ab */
#define FREQTYPE_ALL 0xFF /* 频率类型:全部 */

#define CODE_NONE 0 /* 观测码:无 */
#define CODE_L1C 1 /* 观测码:L1C/A,G1C/A,E1C (GPS,GLONASS,Galileo,QZSS,SBAS) */
#define CODE_L1P 2 /* 观测码:L1P,G1P,B1P (GPS,GLONASS,北斗) */
#define CODE_L1W 3 /* 观测码:L1 Z-track (GPS) */
#define CODE_L1Y 4 /* 观测码:L1Y (GPS) */
#define CODE_L1M 5 /* 观测码:L1M (GPS) */
#define CODE_L1N 6 /* 观测码:L1无码,B1无码 (GPS,北斗) */
#define CODE_L1S 7 /* 观测码:L1C(D) (GPS,QZSS) */
#define CODE_L1L 8 /* 观测码:L1C(P) (GPS,QZSS) */
#define CODE_L1E 9 /* (未使用) */
#define CODE_L1A 10 /* 观测码:E1A,B1A (Galileo,北斗) */
#define CODE_L1B 11 /* 观测码:E1B (Galileo) */
#define CODE_L1X 12 /* 观测码:E1B+C,L1C(D+P),B1D+P (Galileo,QZSS,北斗) */
#define CODE_L1Z 13 /* 观测码:E1A+B+C,L1S (Galileo,QZSS) */
#define CODE_L2C 14 /* 观测码:L2C/A,G1C/A (GPS,GLONASS) */
#define CODE_L2D 15 /* 观测码:L2 L1C/A-(P2-P1) (GPS) */
#define CODE_L2S 16 /* 观测码:L2C(M) (GPS,QZSS) */
#define CODE_L2L 17 /* 观测码:L2C(L) (GPS,QZSS) */
#define CODE_L2X 18 /* 观测码:L2C(M+L),B1_2I+Q (GPS,QZSS,北斗) */
#define CODE_L2P 19 /* 观测码: L2P,G2P (GPS,GLONASS) */
#define CODE_L2W 20 /* 观测码: L2 Z-track (GPS) */
#define CODE_L2Y 21 /* 观测码: L2Y (GPS) */
#define CODE_L2M 22 /* 观测码: L2M (GPS) */
#define CODE_L2N 23 /* 观测码: L2无码 (GPS) */
#define CODE_L5I 24 /* 观测码: L5I,E5aI (GPS,Galileo,QZSS,SBAS) */
#define CODE_L5Q 25 /* 观测码: L5Q,E5aQ (GPS,Galileo,QZSS,SBAS) */
#define CODE_L5X 26 /* 观测码: L5I+Q,E5aI+Q,L5B+C,B2aD+P (GPS,Galileo,QZSS,IRNSS,SBAS,北斗) */
#define CODE_L7I 27 /* 观测码: E5bI,B2bI (Galileo,北斗) */
#define CODE_L7Q 28 /* 观测码: E5bQ,B2bQ (Galileo,北斗) */
#define CODE_L7X 29 /* 观测码: E5bI+Q,B2bI+Q (Galileo,北斗) */
#define CODE_L6A 30 /* 观测码: E6A,B3A (Galileo,北斗) */
#define CODE_L6B 31 /* 观测码: E6B (Galileo) */
#define CODE_L6C 32 /* 观测码: E6C (Galileo) */
#define CODE_L6X 33 /* 观测码: E6B+C,LEXS+L,B3I+Q (Galileo,QZSS,北斗) */
#define CODE_L6Z 34 /* 观测码: E6A+B+C,L6D+E (Galileo,QZSS) */
#define CODE_L6S 35 /* 观测码: L6S (QZSS) */
#define CODE_L6L 36 /* 观测码: L6L (QZSS) */
#define CODE_L8I 37 /* 观测码: E5abI (Galileo) */
#define CODE_L8Q 38 /* 观测码: E5abQ (Galileo) */
#define CODE_L8X 39 /* 观测码: E5abI+Q,B2abD+P (Galileo,北斗) */
#define CODE_L2I 40 /* 观测码: B1_2I (北斗) */
#define CODE_L2Q 41 /* 观测码: B1_2Q (北斗) */
#define CODE_L6I 42 /* 观测码: B3I (北斗) */
#define CODE_L6Q 43 /* 观测码: B3Q (北斗) */
#define CODE_L3I 44 /* 观测码: G3I (GLONASS) */
#define CODE_L3Q 45 /* 观测码: G3Q (GLONASS) */
#define CODE_L3X 46 /* 观测码: G3I+Q (GLONASS) */
#define CODE_L1I 47 /* 观测码: B1I (北斗) (过时) */
#define CODE_L1Q 48 /* 观测码: B1Q (北斗) (过时) */
#define CODE_L5A 49 /* 观测码: L5A SPS (IRNSS) */
#define CODE_L5B 50 /* 观测码: L5B RS(D) (IRNSS) */
#define CODE_L5C 51 /* 观测码: L5C RS(P) (IRNSS) */
#define CODE_L9A 52 /* 观测码: SA SPS (IRNSS) */
#define CODE_L9B 53 /* 观测码: SB RS(D) (IRNSS) */
#define CODE_L9C 54 /* 观测码: SC RS(P) (IRNSS) */
#define CODE_L9X 55 /* 观测码: SB+C (IRNSS) */
#define CODE_L1D 56 /* 观测码: B1D (北斗) */
#define CODE_L5D 57 /* 观测码: L5D(L5S),B2aD (QZSS,北斗) */
#define CODE_L5P 58 /* 观测码: L5P(L5S),B2aP (QZSS,北斗) */
#define CODE_L5Z 59 /* 观测码: L5D+P(L5S) (QZSS) */
#define CODE_L6E 60 /* 观测码: L6E (QZSS) */
#define CODE_L7D 61 /* 观测码: B2bD (北斗) */
#define CODE_L7P 62 /* 观测码: B2bP (北斗) */
#define CODE_L7Z 63 /* 观测码: B2bD+P (北斗) */
#define CODE_L8D 64 /* 观测码: B2abD (北斗) */
#define CODE_L8P 65 /* 观测码: B2abP (北斗) */
#define CODE_L4A 66 /* 观测码: G1aL1OCd (GLONASS) */
#define CODE_L4B 67 /* 观测码: G1aL1OCd (GLONASS) */
#define CODE_L4X 68 /* 观测码: G1aL1OCd+p (GLONASS) */
#define MAXCODE 68 /* 最大观测码数量 */

#define PMODE_DGNSS 1 /* 定位模式:DGNSS*/
#define PMODE_KINEMA 2 /* 定位模式:动态定位 */
// #define PMODE_MOVEB 4 /* 定位模式:移动基线 */
#define PMODE_FIXED 5 /* 定位模式 */

#define SOLF_LLH 0 /* 解决方案格式: 纬度/经度/高度 */
#define SOLF_XYZ 1 /* 解决方案格式: x/y/z-地心坐标 */
#define SOLF_ENU 2 /* 解决方案格式: e/n/u-基线 */
#define SOLF_NMEA 3 /* 解决方案格式: NMEA-183 */
#define SOLF_STAT 4 /* 解决方案格式: 解决方案状态 */
#define SOLF_GSIF 5 /* 解决方案格式: GSI F1/F2 */

#define SOLQ_NONE 0 /* 解决方案状态: 无解决方案 */
#define SOLQ_FIX 1 /* 解决方案状态: 固定解 */
#define SOLQ_FLOAT 2 /* 解决方案状态: 浮动解 */
#define SOLQ_SBAS 3 /* 解决方案状态: SBAS */
#define SOLQ_DGPS 4 /* 解决方案状态: DGPS/DGNSS */
#define SOLQ_SINGLE 5 /* 解决方案状态: 单点定位 */
#define SOLQ_DR 7 /* 解决方案状态: 死记航法 */
#define MAXSOLQ 7 /* 最大解决方案状态数量 */

#define TIMES_GPST 0 /* 时间系统: GPS时间 */
#define TIMES_UTC 1 /* 时间系统: UTC */
#define TIMES_CST 2 /* 时间系统: 北京时间 CST */

#define IONOOPT_OFF 0 /* 电离层选项: 关闭修正 */
#define IONOOPT_BRDC 1 /* 电离层选项: 广播模型 */
#define IONOOPT_SBAS 2 /* 电离层选项: SBAS模型 */
#define IONOOPT_IFLC 3 /* 电离层选项: L1/L2 无电离层组合 */
#define IONOOPT_EST 4 /* 电离层选项: 估计 */
#define IONOOPT_TEC 5 /* 电离层选项: IONEX TEC模型 */
#define IONOOPT_QZS 6 /* 电离层选项: QZSS广播模型 */
#define IONOOPT_STEC 8 /* 电离层选项: 斜路径TEC模型 */

#define TROPOPT_OFF 0 /* 对流层选项: 关闭修正 */
#define TROPOPT_SAAS 1 /* 对流层选项: Saastamoinen模型 */
#define TROPOPT_SBAS 2 /* 对流层选项: SBAS模型 */
#define TROPOPT_EST 3 /* 对流层选项: ZTD估计 */
#define TROPOPT_ESTG 4 /* 对流层选项: ZTD+梯度估计 */
#define TROPOPT_ZTD 5 /* 对流层选项: ZTD修正 */

#define EPHOPT_BRDC 0 /* 星历选项: 广播星历 */
#define EPHOPT_PREC 1 /* 星历选项: 精密星历 */
#define EPHOPT_SBAS 2 /* 星历选项: 广播+SBAS */
#define EPHOPT_SSRAPC 3 /* 星历选项: 广播+SSR_APC */
#define EPHOPT_SSRCOM 4 /* 星历选项: 广播+SSR_COM */

#define ARMODE_OFF 0 /* AR模式: 关闭 */
#define ARMODE_CONT 1 /* AR模式: 连续 */
#define ARMODE_INST 2 /* AR模式: 即时 */
#define ARMODE_FIXHOLD 3 /* AR模式: 固定保持 */
#define ARMODE_WLNL 4 /* AR模式: 宽巷/窄巷 */
#define ARMODE_TCAR 5 /* AR模式: 三载波AR */

#define SBSOPT_LCORR 1 /* SBAS选项: 长期修正 */
#define SBSOPT_FCORR 2 /* SBAS选项: 快速修正 */
#define SBSOPT_ICORR 4 /* SBAS选项: 电离层修正 */
#define SBSOPT_RANGE 8 /* SBAS选项: 测距 */

#define POSOPT_POS 0 /* 定位选项: LLH/XYZ */
#define POSOPT_SINGLE 1 /* 定位选项: 单点定位平均值 */
#define POSOPT_FILE 2 /* 定位选项: 从文件读取 */
#define POSOPT_RINEX 3 /* 定位选项: RINEX头定位 */
#define POSOPT_RTCM 4 /* 定位选项: RTCM/原始站点定位 */

#define STR_MODE_R 0x1 /* 流模式: 读取 */
#define STR_MODE_W 0x2 /* 流模式: 写入 */
#define STR_MODE_RW 0x3 /* 流模式: 读/写 */

#define GEOID_EMBEDDED 0 /* 大地水准面模型: 内嵌大地水准面 */
#define GEOID_EGM96_M150 1 /* 大地水准面模型: EGM96 15×15″ */
#define GEOID_EGM2008_M25 2 /* 大地水准面模型: EGM2008 2.5×2.5″ */
#define GEOID_EGM2008_M10 3 /* 大地水准面模型: EGM2008 1.0×1.0″ */
#define GEOID_GSI2000_M15 4 /* 大地水准面模型: GSI 2000 1.0×1.5″ */
#define GEOID_RAF09 5 /* 大地水准面模型: 法国IGN RAF09 1.5″x2″ */

#define COMMENTH “%” /* 结果注释行指示符 */
#define MSG_DISCONN “$_DISCONNECT\r\n” /* 断开连接消息 */

#define LLI_SLIP 0x01 /* LLI: 周期跳变 */
#define LLI_HALFC 0x02 /* LLI: 未解决的半周期 */
#define LLI_BOCTRK 0x04 /* LLI: mboc信号的boc跟踪 */
#define LLI_HALFA 0x40 /* LLI: 添加半周期 */
#define LLI_HALFS 0x80 /* LLI: 减去半周期 */

#define P2_5 0.03125 /* 2^-5 */
#define P2_6 0.015625 /* 2^-6 */
#define P2_11 4.882812500000000E-04 /* 2^-11 */
#define P2_15 3.051757812500000E-05 /* 2^-15 */
#define P2_17 7.629394531250000E-06 /* 2^-17 */
#define P2_19 1.907348632812500E-06 /* 2^-19 */
#define P2_20 9.536743164062500E-07 /* 2^-20 */
#define P2_21 4.768371582031250E-07 /* 2^-21 */
#define P2_23 1.192092895507810E-07 /* 2^-23 */
#define P2_24 5.960464477539063E-08 /* 2^-24 */
#define P2_27 7.450580596923828E-09 /* 2^-27 */
#define P2_29 1.862645149230957E-09 /* 2^-29 */
#define P2_30 9.313225746154785E-10 /* 2^-30 */
#define P2_31 4.656612873077393E-10 /* 2^-31 */
#define P2_32 2.328306436538696E-10 /* 2^-32 */
#define P2_33 1.164153218269348E-10 /* 2^-33 */
#define P2_35 2.910383045673370E-11 /* 2^-35 */
#define P2_38 3.637978807091710E-12 /* 2^-38 */
#define P2_39 1.818989403545856E-12 /* 2^-39 */
#define P2_40 9.094947017729280E-13 /* 2^-40 */
#define P2_43 1.136868377216160E-13 /* 2^-43 */
#define P2_48 3.552713678800501E-15 /* 2^-48 */
#define P2_50 8.881784197001252E-16 /* 2^-50 */
#define P2_55 2.775557561562891E-17 /* 2^-55 */

#ifdef WIN32
#define thread_t HANDLE
#define lock_t CRITICAL_SECTION
#define initlock(f) InitializeCriticalSection(f)
#define lock(f) EnterCriticalSection(f)
#define unlock(f) LeaveCriticalSection(f)
#define FILEPATHSEP ‘\\’
#else
#define thread_t pthread_t
#define lock_t pthread_mutex_t
#define initlock(f) pthread_mutex_init(f,NULL)
#define lock(f) pthread_mutex_lock(f)
#define unlock(f) pthread_mutex_unlock(f)
#define FILEPATHSEP ‘/’
#endif

/* 类型定义 ———————————————————-*/

typedef struct { /* 时间结构 */
time_t time; /* 由标准time_t表示的时间(秒) */
double sec; /* 1秒内的秒的小数部分 */
} gtime_t;

typedef struct { /* 观测数据记录 */
gtime_t time; /* 接收机采样时间(GPST) */
uint8_t sat, rcv; /* 卫星/接收机编号 */
uint16_t SNR[NFREQ + NEXOBS]; /* 信号强度(0.001 dBHz) */
uint8_t LLI[NFREQ + NEXOBS]; /* 丢锁指示符 */
uint8_t code[NFREQ + NEXOBS]; /* 码指示符(CODE_???) */
double L[NFREQ + NEXOBS]; /* 观测数据载波相位(周期) */
double P[NFREQ + NEXOBS]; /* 观测数据伪距(米) */
float D[NFREQ + NEXOBS]; /* 观测数据多普勒频率(Hz) */
} obsd_t;

typedef struct { /* 观测数据 */
int n, nmax; /* 观测数据的数量/分配的数量 */
obsd_t* data; /* 观测数据记录 */
} obs_t;

typedef struct { /* 地球自转参数数据类型 */
double mjd; /* MJD(天) */
double xp, yp; /* 极移偏差(弧度) */
double xpr, ypr; /* 极移偏差变化率(弧度/天) */
double ut1_utc; /* UT1-UTC(秒) */
double lod; /* 日长变化(秒/天) */
} erpd_t;

typedef struct { /* 地球自转参数类型 */
int n, nmax; /* 数据的数量和最大数量 */
erpd_t* data; /* 地球自转参数数据 */
} erp_t;

typedef struct { /* 天线参数类型 */
int sat; /* 卫星编号(0:接收机) */
char type[MAXANT]; /* 天线类型 */
char code[MAXANT]; /* 序列号或卫星编码 */
gtime_t ts, te; /* 有效时间的开始和结束 */
double off[NFREQ][3]; /* 相位中心偏移 e/n/u 或 x/y/z(米) */
double var[NFREQ][19]; /* 相位中心变化(米) */
/* el=90,85,…,0 或者 nadir=0,1,2,3,…(度) */
} pcv_t;

typedef struct { /* 天线参数类型 */
int n, nmax; /* 数据数量/分配的数量 */
pcv_t* pcv; /* 天线参数数据 */
} pcvs_t;

typedef struct { /* 星历类型 */
int sat; /* 卫星编号 */
int svh; /* 卫星健康状态 (0: 正常) */
int svconf; /* AS 和 SV 配置 */
int week; /* GPS/QZS: GPS周, GAL: 伽利略周 */
gtime_t toa; /* Toa */
/* SV 轨道参数 */
double A, e, i0, OMG0, omg, M0, OMGd;
double toas; /* 周内 Toa (秒) */
double f0, f1; /* SV 时钟参数 (af0, af1) */
} alm_t;

typedef struct { /* GPS/QZS/GAL 广播星历类型 */
int sat; /* 卫星编号 */
int iode, iodc; /* IODE, IODC */
int sva; /* 卫星精度 (URA 指数) */
int svh; /* 卫星健康状态 (0: 正常) */
int week; /* GPS/QZS: GPS周, GAL: 伽利略周 */
int code; /* GPS/QZS: L2 上的码 */
/* GAL: 数据源定义为 RINEX 3.03 */
/* BDS: 数据源 (0: 未知, 1: B1I, 2: B1Q, 3: B2I, 4: B2Q, 5: B3I, 6: B3Q) */
int flag; /* GPS/QZS: L2 P 数据标志 */
/* BDS: 导航类型 (0: 未知, 1: IGSO/MEO, 2: GEO) */
gtime_t toe, toc, ttr; /* Toe, Toc, T_trans */
/* SV 轨道参数 */
double A, e, i0, OMG0, omg, M0, deln, OMGd, idot;
double crc, crs, cuc, cus, cic, cis;
double toes; /* 周内 Toe (秒) */
double fit; /* 拟合间隔 (小时) */
double f0, f1, f2; /* SV 时钟参数 (af0, af1, af2) */
double tgd[6]; /* 群延迟参数 */
/* GPS/QZS: tgd[0]=TGD */
/* GAL: tgd[0]=BGD_E1E5a, tgd[1]=BGD_E1E5b */
/* BDS: tgd[0]=TGD_B1I, tgd[1]=TGD_B2I/B2b, tgd[2]=TGD_B1Cp */
/* tgd[3]=TGD_B2ap, tgd[4]=ISC_B1Cd, tgd[5]=ISC_B2ad */
double Adot, ndot; /* CNAV 的 Adot, ndot */
} eph_t;

typedef struct { /* GLONASS 广播星历类型 */
int sat; /* 卫星编号 */
int iode; /* IODE (tb 字段的第0-6位) */
int frq; /* 卫星频率编号 */
int svh, sva, age; /* 卫星健康状态、精度、工作年限 */
gtime_t toe; /* 星历时间 (GPST) */
gtime_t tof; /* 消息帧时间 (GPST) */
double pos[3]; /* 卫星位置 (ECEF) (米) */
double vel[3]; /* 卫星速度 (ECEF) (米/秒) */
double acc[3]; /* 卫星加速度 (ECEF) (米/秒^2) */
double taun, gamn; /* SV 时钟偏差 (秒)/相对频率偏差 */
double dtaun; /* L1 和 L2 之间的延迟 (秒) */
} geph_t;

typedef struct { /* 精密星历类型 */
gtime_t time; /* 时间 (GPST) */
int index; /* 多文件的星历索引 */
double pos[MAXSAT][4]; /* 卫星位置/时钟 (ECEF) (米|秒) */
float std[MAXSAT][4]; /* 卫星位置/时钟标准差 (米|秒) */
double vel[MAXSAT][4]; /* 卫星速度/时钟速率 (米/秒|秒/秒) */
float vst[MAXSAT][4]; /* 卫星速度/时钟速率标准差 (米/秒|秒/秒) */
float cov[MAXSAT][3]; /* 卫星位置协方差 (米^2) */
float vco[MAXSAT][3]; /* 卫星速度协方差 (米^2) */
} peph_t;

typedef struct { /* 精密时钟类型 */
gtime_t time; /* 时间 (GPST) */
int index; /* 多文件的时钟索引 */
double clk[MAXSAT][1]; /* 卫星时钟 (秒) */
float std[MAXSAT][1]; /* 卫星时钟标准差 (秒) */
} pclk_t;

typedef struct { /* SBAS 星历类型 */
int sat; /* 卫星编号 */
gtime_t t0; /* 参考历元时间 (GPST) */
gtime_t tof; /* 消息帧时间 (GPST) */
int sva; /* 卫星精度 (URA 指数) */
int svh; /* 卫星健康状态 (0: 正常) */
double pos[3]; /* 卫星位置 (米) (ECEF) */
double vel[3]; /* 卫星速度 (米/秒) (ECEF) */
double acc[3]; /* 卫星加速度 (米/秒^2) (ECEF) */
double af0, af1; /* 卫星时钟偏差/漂移 (秒, 秒/秒) */
} seph_t;

typedef struct { /* NORAD TLE 数据类型 */
char name[32]; /* 常用名称 */
char alias[32]; /* 别名 */
char satno[16]; /* 卫星目录编号 */
char satclass; /* 分类 */
char desig[16]; /* 国际代号 */
gtime_t epoch; /* 元素集历元 (UTC) */
double ndot; /* 平均运动的一阶导数 */
double nddot; /* 平均运动的二阶导数 */
double bstar; /* B* 阻力项 */
int etype; /* 元素集类型 */
int eleno; /* 元素编号 */
double inc; /* 轨道倾角 (度) */
double OMG; /* 升交点赤经 (度) */
double ecc; /* 离心率 */
double omg; /* 近地点幅角 (度) */
double M; /* 平近点角 (度) */
double n; /* 平均运动 (转/天) */
int rev; /* 历元时的轨道圈数 */
} tled_t;

typedef struct { /* NORAD TLE (两行根数) 类型 */
int n, nmax; /* 两行根数数据的数量/最大数量 */
tled_t* data; /* NORAD TLE 数据 */
} tle_t;

typedef struct { /* TEC 网格类型 */
gtime_t time; /* 历元时间 (GPST) */
int ndata[3]; /* TEC 网格数据大小 {纬度数, 经度数, 高度数} */
double rb; /* 地球半径 (公里) */
double lats[3]; /* 纬度起始值/间隔 (度) */
double lons[3]; /* 经度起始值/间隔 (度) */
double hgts[3]; /* 高度起始值/间隔 (公里) */
double* data; /* TEC 网格数据 (TECU) */
float* rms; /* 均方根值 (TECU) */
} tec_t;

typedef struct { /* SBAS 消息类型 */
int week, tow; /* 接收时间 */
uint8_t prn, rcv; /* SBAS 卫星 PRN, 接收器编号 */
uint8_t msg[29]; /* SBAS 消息 (226比特) 以0填充 */
} sbsmsg_t;

typedef struct { /* SBAS 消息集合类型 */
int n, nmax; /* SBAS 消息数量/已分配数量 */
sbsmsg_t* msgs; /* SBAS 消息 */
} sbs_t;

typedef struct { /* SBAS 快速校正类型 */
gtime_t t0; /* 适用时间 (TOF) */
double prc; /* 伪距校正 (PRC) (米) */
double rrc; /* 伪距速率校正 (RRC) (米/秒) */
double dt; /* 伪距速率校正时间差 (秒) */
int iodf; /* 快速校正数据日期 (IODF) */
int16_t udre; /* UDRE+1 */
int16_t ai; /* 衰减因子指示符 */
} sbsfcorr_t;

typedef struct { /* SBAS 长期卫星误差校正类型 */
gtime_t t0; /* 校正时间 */
int iode; /* 星历数据日期 (IODE) */
double dpos[3]; /* 位置差 (米) (ECEF) */
double dvel[3]; /* 速度差 (米/秒) (ECEF) */
double daf0, daf1; /* 时钟偏差/漂移差 (秒, 秒/秒) */
} sbslcorr_t;

typedef struct { /* SBAS 卫星校正类型 */
int sat; /* 卫星编号 */
sbsfcorr_t fcorr; /* 快速校正 */
sbslcorr_t lcorr; /* 长期校正 */
} sbssatp_t;

typedef struct { /* SBAS 卫星校正集合类型 */
int iodp; /* 数据日期掩码 (IODP) */
int nsat; /* 卫星数量 */
int tlat; /* 系统延迟 (秒) */
sbssatp_t sat[MAXSAT]; /* 卫星校正 */
} sbssat_t;

typedef struct { /* SBAS 电离层校正类型 */
gtime_t t0; /* 校正时间 */
int16_t lat, lon; /* 纬度/经度 (度) */
int16_t give; /* GIVI+1 */
float delay; /* 垂直延迟估计 (米) */
} sbsigp_t;

typedef struct { /* IGP 波段类型 */
int16_t x; /* 经度/纬度 (度) */
const int16_t* y; /* 纬度/经度 (度) */
uint8_t bits; /* IGP 掩码起始位 */
uint8_t bite; /* IGP 掩码结束位 */
} sbsigpband_t;

typedef struct { /* SBAS 电离层校正集合类型 */
int iodi; /* 电离层校正数据日期 (IODI) */
int nigp; /* IGP 数量 */
sbsigp_t igp[MAXNIGP]; /* 电离层校正 */
} sbsion_t;

typedef struct { /* DGPS/GNSS 校正类型 */
gtime_t t0; /* 校正时间 */
double prc; /* 伪距校正 (PRC) (米) */
double rrc; /* 伪距速率校正 (RRC) (米/秒) */
int iod; /* 数据日期 (IOD) */
double udre; /* UDRE */
} dgps_t;

typedef struct { /* SSR 校正类型 */
gtime_t t0[6]; /* 历元时间 (GPST) {星历,时钟,高频时钟,URA,偏差,相位偏差} */
double udi[6]; /* SSR 更新间隔 (秒) */
int iod[6]; /* SSR 数据日期 {星历,时钟,高频时钟,URA,偏差,相位偏差} */
int iode; /* 数据日期 */
int iodcrc; /* 北斗/SBAS 数据日期 CRC */
int ura; /* URA 指示符 */
int refd; /* 卫星参考基准 (0:ITRF,1:区域) */
double deph[3]; /* 轨道改正数 {径向,沿轨,交叉轨} (米) */
double ddeph[3]; /* 轨道改正速率 {径向,沿轨,交叉轨} (米/秒) */
double dclk[3]; /* 时钟改正数 {c0,c1,c2} (米, 米/秒, 米/秒^2) */
double hrclk; /* 高频时钟校正 (米) */
float cbias[MAXCODE]; /* 码偏差 (米) */
double pbias[MAXCODE]; /* 相位偏差 (米) */
float stdpb[MAXCODE]; /* 相位偏差标准差 (米) */
double yaw_ang, yaw_rate; /* 偏航角和偏航速率 (度,度/秒) */
uint8_t update; /* 更新标志 (0:无更新,1:更新) */
} ssr_t;

typedef struct { /* 导航数据类型 */
int n, nmax; /* 广播星历数量/最大数量 */
int ng, ngmax; /* GLONASS 星历数量/最大数量 */
int ns, nsmax; /* SBAS 星历数量/最大数量 */
int ne, nemax; /* 精密星历数量/最大数量 */
int nc, ncmax; /* 精密时钟数量/最大数量 */
int na, namax; /* 星历年鉴数据数量/最大数量 */
int nt, ntmax; /* TEC 网格数据数量/最大数量 */
eph_t* eph; /* GPS/QZS/GAL/BDS/IRN 星历 */
geph_t* geph; /* GLONASS 星历 */
seph_t* seph; /* SBAS 星历 */
peph_t* peph; /* 精密星历 */
pclk_t* pclk; /* 精密时钟 */
alm_t* alm; /* 星历年鉴数据 */
tec_t* tec; /* TEC 网格数据 */
erp_t erp; /* 地球自转参数 */
double utc_gps[8]; /* GPS delta-UTC 参数 {A0,A1,Tot,WNt,dt_LS,WN_LSF,DN,dt_LSF} */
double utc_glo[8]; /* GLONASS UTC 时间参数 {tau_C,tau_GPS} */
double utc_gal[8]; /* Galileo UTC 参数 */
double utc_qzs[8]; /* QZS UTC 参数 */
double utc_cmp[8]; /* BeiDou UTC 参数 */
double utc_irn[9]; /* IRNSS UTC 参数 {A0,A1,Tot,…,dt_LSF,A2} */
double utc_sbs[4]; /* SBAS UTC 参数 */
double ion_gps[8]; /* GPS 电离层模型参数 {a0,a1,a2,a3,b0,b1,b2,b3} */
double ion_gal[4]; /* Galileo 电离层模型参数 {ai0,ai1,ai2,0} */
double ion_qzs[8]; /* QZSS 电离层模型参数 {a0,a1,a2,a3,b0,b1,b2,b3} */
double ion_cmp[8]; /* BeiDou 电离层模型参数 {a0,a1,a2,a3,b0,b1,b2,b3} */
double ion_irn[8]; /* IRNSS 电离层模型参数 {a0,a1,a2,a3,b0,b1,b2,b3} */
int glo_fcn[32]; /* GLONASS FCN + 8 */
double cbias[MAXSAT][3]; /* 卫星 DCB (0:P1-P2,1:P1-C1,2:P2-C2) (米) */
double rbias[MAXRCV][2][3]; /* 接收器 DCB (0:P1-P2,1:P1-C1,2:P2-C2) (米) */
pcv_t pcvs[MAXSAT]; /* 卫星天线 PCV */
sbssat_t sbssat; /* SBAS 卫星校正 */
sbsion_t sbsion[MAXBAND + 1]; /* SBAS 电离层校正 */
dgps_t dgps[MAXSAT]; /* DGPS 校正 */
ssr_t ssr[MAXSAT]; /* SSR 校正 */
} nav_t;

typedef struct { /* 站点参数类型 */
char name[MAXANT]; /* 标记名称 */
char marker[MAXANT]; /* 标记编号 */
char antdes[MAXANT]; /* 天线描述 */
char antsno[MAXANT]; /* 天线序列号 */
char rectype[MAXANT]; /* 接收器类型描述 */
char recver[MAXANT]; /* 接收器固件版本 */
char recsno[MAXANT]; /* 接收器序列号 */
int antsetup; /* 天线安装编号 */
int itrf; /* ITRF 实现年 */
int deltype; /* 天线偏移类型 (0:enu,1:xyz) */
double pos[3]; /* 站点位置 (ECEF) (米) */
double del[3]; /* 天线位置偏移 (东/北/上 或 x/y/z) (米) */
double hgt; /* 天线高度 (米) */
int glo_cp_align; /* GLONASS 码相位对齐 (0:否,1:是) */
double glo_cp_bias[4]; /* GLONASS 码相位偏差 {1C,1P,2C,2P} (米) */
} sta_t;

typedef struct { /* 解算类型 */
gtime_t time; /* 时间 (GPST) */
double rr[6]; /* 位置/速度 (米|米/秒) */
/* {x,y,z,vx,vy,vz} 或 {e,n,u,ve,vn,vu} */
float qr[6]; /* 位置方差/协方差 (平方米) */
/* {c_xx,c_yy,c_zz,c_xy,c_yz,c_zx} 或 */
/* {c_ee,c_nn,c_uu,c_en,c_nu,c_ue} */
float qv[6]; /* 速度方差/协方差 (平方米/秒²) */
double dtr[6]; /* 接收机时钟偏差 (秒) */
uint8_t type; /* 类型 (0:xyz-ecef,1:enu-baseline) */
uint8_t stat; /* 解算状态 (SOLQ_???) */
uint8_t ns; /* 有效卫星数量 */
float age; /* 差分龄期 (秒) */
float ratio; /* AR 比例因子 */
float thres; /* AR 比例阈值 */
} sol_t;

typedef struct { /* 解算缓冲类型 */
int n, nmax; /* 解算数量/缓冲最大数量 */
int cyclic; /* 循环缓冲标志 */
int start, end; /* 开始/结束索引 */
gtime_t time; /* 当前解算时间 */
sol_t* data; /* 解算数据 */
double rb[3]; /* 参考位置 {x,y,z} (ecef) (米) */
uint8_t buff[MAXSOLMSG + 1]; /* 消息缓冲区 */
int nb; /* 消息缓冲区字节数 */
} solbuf_t;

typedef struct { /* 解算状态类型 */
gtime_t time; /* 时间 (GPST) */
uint8_t sat; /* 卫星编号 */
uint8_t frq; /* 频率 (1:L1,2:L2,…) */
float az, el; /* 方位角/高度角 (弧度) */
float resp; /* 伪距残差 (米) */
float resc; /* 载波相位残差 (米) */
uint8_t flag; /* 标志: (vsat<<5)+(slip<<3)+fix */
uint16_t snr; /* 信号强度 (*SNR_UNIT dBHz) */
uint16_t lock; /* 锁定计数 */
uint16_t outc; /* 断信计数 */
uint16_t slipc; /* 周跳计数 */
uint16_t rejc; /* 拒绝计数 */
} solstat_t;

typedef struct { /* 解算状态缓冲类型 */
int n, nmax; /* 解算状态数量/缓冲最大数量 */
solstat_t* data; /* 解算状态数据 */
} solstatbuf_t;

typedef struct { /* RINEX 控制结构类型 */
gtime_t time; /* 消息时间 */
double ver; /* RINEX 版本 */
char type; /* RINEX 文件类型 (‘O’,’N’,…) */
int sys; /* 导航系统 */
int tsys; /* 时间系统 */
char tobs[8][MAXOBSTYPE][4]; /* RINEX 观测类型 */
obs_t obs; /* 观测数据 */
nav_t nav; /* 导航数据 */
sta_t sta; /* 站点信息 */
int ephsat; /* 输入星历卫星编号 */
int ephset; /* 输入星历集 (0-1) */
char opt[256]; /* RINEX 依赖选项 */
} rnxctr_t;

typedef struct { /* 下载 URL 类型 */
char type[32]; /* 数据类型 */
char path[1024]; /* URL 路径 */
char dir[1024]; /* 本地目录 */
double tint; /* 时间间隔 (秒) */
} url_t;

typedef struct { /* 选项类型 */
const char* name; /* 选项名称 */
int format; /* 选项格式 (0:int,1:double,2:string,3:enum) */
void* var; /* 选项变量指针 */
const char* comment; /* 选项注释/枚举标签/单位 */
} opt_t;

typedef struct { /* SNR 掩码类型 */
int ena[2]; /* 启用标志 {流动站,基站} */
double mask[NFREQ][9]; /* 掩码 (dBHz) 在 5,10,…85 度 */
} snrmask_t;

typedef struct { /* 处理选项类型 */
int mode; /* 定位模式 (PMODE_???) */
int soltype; /* 解算类型 (0:前向,1:后向,2:组合) */
int nf; /* 频率数量 (1:L1,2:L1+L2,3:L1+L2+L5) */
int navsys; /* 导航系统 */
double elmin; /* 高度角掩码 (弧度) */
snrmask_t snrmask; /* SNR 掩码 */
int sateph; /* 卫星星历/钟差 (EPHOPT_???) */
int modear; /* AR 模式 (0:关闭,1:连续,2:瞬时,3:固定保持) */
int glomodear; /* GLONASS AR 模式 (0:关闭,1:开启,2:自动校准,3:扩展校准) */
int bdsmodear; /* 北斗 AR 模式 (0:关闭,1:开启) */
int maxout; /* 观测中断计数以重置偏差 */
int minlock; /* 最小锁定计数以固定模糊度 */
int minfix; /* 最小固定计数以保持模糊度 */
int armaxiter; /* 解决模糊度的最大迭代次数 */
int ionoopt; /* 电离层选项 (IONOOPT_???) */
int tropopt; /* 对流层选项 (TROPOPT_???) */
int dynamics; /* 动力学模型 (0:无,1:速度,2:加速度) */
int tidecorr; /* 地球潮汐校正 (0:关闭,1:固体,2:固体+OTL+极移) */
int niter; /* 滤波迭代次数 */
int codesmooth; /* 码平滑窗口大小 (0:无) */
int intpref; /* 插值参考观测 (用于后处理) */
int sbascorr; /* SBAS 校正选项 */
int sbassatsel; /* SBAS 卫星选择 (0:全部) */
int rovpos; /* 固定模式流动站位置 */
int refpos; /* 相对模式基站位置 */
/* (0:在 prcopt 中的位置, 1:单点定位平均值, */
/* 2:从文件读取, 3:rinex 头文件, 4:rtcm 位置) */
double eratio[NFREQ]; /* 码/相位误差比率 */
double err[5]; /* 测量误差因子 */
/* [0]:保留 */
/* [1-3]:相位误差因子 a/b/c (米) */
/* [4]:多普勒频率 (赫兹) */
double std[3]; /* 初始状态标准差 [0]偏差,[1]电离层 [2]对流层 */
double prn[6]; /* 过程噪声标准差 [0]偏差,[1]电离层 [2]对流层 [3]加速度水平 [4]加速度垂直 [5] 位置 */
double sclkstab; /* 卫星钟稳定性 (秒/秒) */
double thresar[8]; /* AR 验证阈值 */
double elmaskar; /* 升起卫星的 AR 高度角掩码 (度) */
double elmaskhold; /* 保持模糊度的高度角掩码 (度) */
double thresslip; /* 几何自由相位的周跳阈值 (米) */
double maxtdiff; /* 最大时间差 (秒) */
double maxinno; /* 创新值拒绝阈值 (米) */
double maxgdop; /* GDOP 拒绝阈值 */
double baseline[2]; /* 基线长度约束 {常数,标准差} (米) */
double ru[3]; /* 固定模式流动站位置 {x,y,z} (ecef) (米) */
double rb[3]; /* 相对模式基站位置 {x,y,z} (ecef) (米) */
char anttype[2][MAXANT]; /* 天线类型 {流动站,基站} */
double antdel[2][3]; /* 天线偏差 {{rov_e,rov_n,rov_u},{ref_e,ref_n,ref_u}} */
pcv_t pcvr[2]; /* 接收机天线参数 {流动站,基站} */
uint8_t exsats[MAXSAT]; /* 排除卫星 (1:排除,2:包括) */
int maxaveep; /* 最大平均历元数 */
int initrst; /* 重启初始化 */
int outsingle; /* 由 dgps/浮动/固定/ppp 中断输出单点解算 */
char rnxopt[2][256]; /* RINEX 选项 {流动站,基站} */
int posopt[6]; /* 定位选项 */
int syncsol; /* 解算同步模式 (0:关闭,1:开启) */
double odisp[2][6 * 11]; /* 海洋潮汐加载参数 {流动站,基站} */
int freqopt; /* 禁用 L2-AR */
char pppopt[256]; /* PPP 选项 */
} prcopt_t;

typedef struct { /* 解算选项类型 */
int posf; /* 解算格式 (SOLF_???) */
int times; /* 时间系统 (TIMES_???) */
int timef; /* 时间格式 (0:sssss.s,1:yyyy/mm/dd hh:mm:ss.s) */
int timeu; /* 时间小数点后的位数 */
int degf; /* 纬度/经度格式 (0:ddd.ddd,1:ddd mm ss) */
int outhead; /* 输出头 (0:否,1:是) */
int outopt; /* 输出处理选项 (0:否,1:是) */
int outvel; /* 输出速度选项 (0:否,1:是) */
int datum; /* 基准 (0:WGS84,1:Tokyo) */
int height; /* 高度 (0:椭球高,1:大地高) */
int geoid; /* 大地水准面模型 (0:EGM96,1:JGD2000) */
int solstatic; /* 静态模式解算 (0:全部,1:单点) */
int sstat; /* 解算统计级别 (0:关闭,1:状态,2:残差) */
int trace; /* 调试跟踪级别 (0:关闭,1-5:调试) */
double nmeaintv[2]; /* NMEA 输出间隔 (秒) (<0:无,0:全部) */
/* nmeaintv[0]:gprmc,gpgga,nmeaintv[1]:gpgsv */
char sep[64]; /* 字段分隔符 */
char prog[64]; /* 程序名称 */
double maxsolstd; /* 解算输出的最大标准差 (米) (0:全部) */
} solopt_t;

typedef struct { /* 文件选项类型 */
char satantp[MAXSTRPATH]; /* 卫星天线参数文件 */
char rcvantp[MAXSTRPATH]; /* 接收机天线参数文件 */
char stapos[MAXSTRPATH]; /* 站点位置文件 */
char geoid[MAXSTRPATH]; /* 外部大地水准面数据文件 */
char iono[MAXSTRPATH]; /* 电离层数据文件 */
char dcb[MAXSTRPATH]; /* DCB 数据文件 */
char eop[MAXSTRPATH]; /* EOP 数据文件 */
char blq[MAXSTRPATH]; /* 海洋潮汐加载 BLQ 文件 */
char tempdir[MAXSTRPATH]; /* FTP/HTTP 临时目录 */
char geexe[MAXSTRPATH]; /* Google Earth 执行文件 */
char solstat[MAXSTRPATH]; /* 解算统计文件 */
char trace[MAXSTRPATH]; /* 调试跟踪文件 */
} filopt_t;

typedef struct { /* RINEX 选项类型 */
gtime_t ts, te; /* 起始/结束时间 */
double tint; /* 时间间隔 (秒) */
double ttol; /* 时间容差 (秒) */
double tunit; /* 多会话时间单位 (秒) */
int rnxver; /* RINEX 版本 (x100) */
int navsys; /* 导航系统 */
int obstype; /* 观测类型 */
int freqtype; /* 频率类型 */
char mask[7][64]; /* 码掩码 {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */
char staid[32]; /* RINEX 文件名的站点编号 */
char prog[32]; /* 程序 */
char runby[32]; /* 运行者 */
char marker[64]; /* 标记名称 */
char markerno[32]; /* 标记编号 */
char markertype[32]; /* 标记类型 (ver.3) */
char name[2][32]; /* 观测员/机构 */
char rec[3][32]; /* 接收机编号/类型/版本 */
char ant[3][32]; /* 天线编号/类型 */
double apppos[3]; /* 近似位置 x/y/z */
double antdel[3]; /* 天线偏差 h/e/n */
double glo_cp_bias[4]; /* GLONASS 码相位偏差 (米) */
char comment[MAXCOMMENT][64]; /* 注释 */
char rcvopt[256]; /* 接收机依赖选项 */
uint8_t exsats[MAXSAT]; /* 排除的卫星 */
int glofcn[32]; /* GLONASS 频率通道号+8 */
int outiono; /* 输出电离层修正 */
int outtime; /* 输出时间系统修正 */
int outleaps; /* 输出闰秒 */
int autopos; /* 自动近似位置 */
int phshift; /* 相位偏移修正 */
int halfcyc; /* 半周期修正 */
int sep_nav; /* 分离的导航文件 */
gtime_t tstart; /* 首次观测时间 */
gtime_t tend; /* 最后观测时间 */
gtime_t trtcm; /* RTCM 近似日志开始时间 */
char tobs[7][MAXOBSTYPE][4]; /* 观测类型 {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */
double shift[7][MAXOBSTYPE]; /* 相位偏移 (周期) {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */
int nobs[7]; /* 观测类型数量 {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */
} rnxopt_t;

typedef struct { /* 卫星状态类型 */
uint8_t sys; /* 导航系统 */
uint8_t vs; /* 有效卫星标志 */
double azel[2]; /* 方位角/高度角 {az,el} (弧度) */
double resp[NFREQ]; /* 伪距残差 (米) */
double resc[NFREQ]; /* 载波相位残差 (米) */
uint8_t vsat[NFREQ]; /* 有效卫星标志 */
uint16_t snr[NFREQ]; /* 信号强度 (*SNR_UNIT dBHz) */
uint8_t fix[NFREQ]; /* 模糊度固定标志 (1:固定,2:浮动,3:保持) */
uint8_t slip[NFREQ]; /* 周跳标志 */
uint8_t half[NFREQ]; /* 半周期有效标志 */
int lock[NFREQ]; /* 相位锁定计数器 */
uint32_t outc[NFREQ]; /* 相位观测中断计数器 */
uint32_t slipc[NFREQ]; /* 周跳计数器 */
uint32_t rejc[NFREQ]; /* 拒绝计数器 */
double gf[NFREQ – 1]; /* 几何自由相位 (米) */
double mw[NFREQ – 1]; /* MW-LC (米) */
double phw; /* 相位缠绕 (周期) */
gtime_t pt[2][NFREQ]; /* 之前的载波相位时间 */
double ph[2][NFREQ]; /* 之前的载波相位观测值 (周期) */
} ssat_t;

typedef struct { /* 模糊度控制类型 */
gtime_t epoch[4]; /* 最后一个历元 */
int n[4]; /* 历元数 */
double LC[4]; /* 线性组合平均值 */
double LCv[4]; /* 线性组合方差 */
int fixcnt; /* 固定计数 */
char flags[MAXSAT]; /* 固定标志 */
} ambc_t;

typedef struct { /* RTK 控制/结果类型 */
sol_t sol; /* RTK 解算 */
double rb[6]; /* 基站位置/速度 (ecef) (米|米/秒) */
int nx, na; /* 浮动状态数/固定状态数 */
double tt; /* 当前与之前的时间差 (秒) */
double* x, * P; /* 浮动状态及其协方差 */
double* xa, * Pa; /* 固定状态及其协方差 */
int nfix; /* 连续固定的模糊度数 */
ambc_t ambc[MAXSAT]; /* 模糊度控制 */
ssat_t ssat[MAXSAT]; /* 卫星状态 */
int neb; /* 错误消息缓冲区中的字节数 */
char errbuf[MAXERRMSG]; /* 错误消息缓冲区 */
prcopt_t opt; /* 处理选项 */
} rtk_t;

typedef void fatalfunc_t(const char*); /* 致命回调函数类型 */

/* 全局变量 ———————————————————-*/
extern const double chisqr[]; /* 卡方(n) 表 (alpha=0.001) */
extern const prcopt_t prcopt_default; /* 默认定位选项 */
extern const solopt_t solopt_default; /* 默认解输出选项 */
extern const char* formatstrs[]; /* 流格式字符串 */
extern opt_t sysopts[]; /* 系统选项表 */

/* 卫星、系统、码函数 ————————————–*/
EXPORT int satno(int sys, int prn);
EXPORT int satsys(int sat, int* prn);
EXPORT int satid2no(const char* id);
EXPORT void satno2id(int sat, char* id);
EXPORT uint8_t obs2code(const char* obs);
EXPORT char* code2obs(uint8_t code);
EXPORT double code2freq(int sys, uint8_t code, int fcn);
EXPORT double sat2freq(int sat, uint8_t code, const nav_t* nav);
EXPORT int code2idx(int sys, uint8_t code);
EXPORT int satexclude(int sat, double var, int svh, const prcopt_t* opt);
EXPORT int testsnr(int base, int freq, double el, double snr,
const snrmask_t* mask);
EXPORT void setcodepri(int sys, int idx, const char* pri);
EXPORT int getcodepri(int sys, uint8_t code, const char* opt);

/* 矩阵和向量函数 ———————————————–*/
EXPORT double* mat(int n, int m);
EXPORT int* imat(int n, int m);
EXPORT double* zeros(int n, int m);
EXPORT double* eye(int n);
EXPORT double dot(const double* a, const double* b, int n);
EXPORT double norm(const double* a, int n);
EXPORT void cross3(const double* a, const double* b, double* c);
EXPORT int normv3(const double* a, double* b);
EXPORT void matcpy(double* A, const double* B, int n, int m);
EXPORT void matmul(const char* tr, int n, int k, int m, double alpha,
const double* A, const double* B, double beta, double* C);
EXPORT int matinv(double* A, int n);
EXPORT int solve(const char* tr, const double* A, const double* Y, int n,
int m, double* X);
EXPORT int lsq(const double* A, const double* y, int n, int m, double* x,
double* Q);
EXPORT int filter(double* x, double* P, const double* H, const double* v,
const double* R, int n, int m);
EXPORT int smoother(const double* xf, const double* Qf, const double* xb,
const double* Qb, int n, double* xs, double* Qs);

EXPORT void add_fatal(fatalfunc_t* func);

/* 时间和字符串函数 ————————————————-*/
EXPORT double str2num(const char* s, int i, int n);
EXPORT int str2time(const char* s, int i, int n, gtime_t* t);
EXPORT void time2str(gtime_t t, char* str, int n);
EXPORT gtime_t epoch2time(const double* ep);
EXPORT void time2epoch(gtime_t t, double* ep);
EXPORT gtime_t gpst2time(int week, double sec);
EXPORT double time2gpst(gtime_t t, int* week);
EXPORT gtime_t gst2time(int week, double sec);
EXPORT double time2gst(gtime_t t, int* week);
EXPORT gtime_t bdt2time(int week, double sec);
EXPORT double time2bdt(gtime_t t, int* week);
EXPORT char* time_str(gtime_t t, int n);
EXPORT gtime_t timeadd(gtime_t t, double sec);
EXPORT double timediff(gtime_t t1, gtime_t t2);
EXPORT gtime_t gpst2utc(gtime_t t);
EXPORT gtime_t utc2gpst(gtime_t t);
EXPORT gtime_t gpst2bdt(gtime_t t);
EXPORT gtime_t bdt2gpst(gtime_t t);
EXPORT gtime_t timeget(void);
EXPORT void timeset(gtime_t t);
EXPORT void timereset(void);
EXPORT double time2doy(gtime_t t);
EXPORT double utc2gmst(gtime_t t, double ut1_utc);
EXPORT int read_leaps(const char* file);
EXPORT int adjgpsweek(int week);
EXPORT uint32_t tickget(void);
EXPORT void sleepms(int ms);
EXPORT int reppath(const char* path, char* rpath, gtime_t time, const char* rov, const char* base);
EXPORT int reppaths(const char* path, char* rpaths[], int nmax, gtime_t ts, gtime_t te, const char* rov, const char* base);

/* 坐标转换函数 ————————————————*/
EXPORT void ecef2pos(const double* r, double* pos);
EXPORT void pos2ecef(const double* pos, double* r);
EXPORT void ecef2enu(const double* pos, const double* r, double* e);
EXPORT void enu2ecef(const double* pos, const double* e, double* r);
EXPORT void covenu(const double* pos, const double* P, double* Q);
EXPORT void covecef(const double* pos, const double* Q, double* P);
EXPORT void xyz2enu(const double* pos, double* E);
EXPORT void eci2ecef(gtime_t tutc, const double* erpv, double* U, double* gmst);
EXPORT void deg2dms(double deg, double* dms, int ndec);
EXPORT double dms2deg(const double* dms);

/* 输入和输出函数 ————————————————*/
EXPORT void readpos(const char* file, const char* rcv, double* pos);
EXPORT int sortobs(obs_t* obs);
EXPORT void uniqnav(nav_t* nav);
EXPORT int screent(gtime_t time, gtime_t ts, gtime_t te, double tint);
EXPORT int readnav(const char* file, nav_t* nav);
EXPORT int savenav(const char* file, const nav_t* nav);
EXPORT void freeobs(obs_t* obs);
EXPORT void freenav(nav_t* nav, int opt);

/* 调试跟踪函数 —————————————————–*/
EXPORT void traceopen(const char* file);
EXPORT void traceclose(void);
EXPORT void tracelevel(int level);
EXPORT void trace(int level, const char* format, …);
EXPORT void tracet(int level, const char* format, …);
EXPORT void tracemat(int level, const double* A, int n, int m, int p, int q);
EXPORT void traceobs(int level, const obsd_t* obs, int n);
EXPORT void tracenav(int level, const nav_t* nav);
EXPORT void tracegnav(int level, const nav_t* nav);
EXPORT void tracehnav(int level, const nav_t* nav);
EXPORT void tracepeph(int level, const nav_t* nav);
EXPORT void tracepclk(int level, const nav_t* nav);
EXPORT void traceb(int level, const uint8_t* p, int n);

/* 平台相关函数 ———————————————-*/
EXPORT int execcmd(const char* cmd);
EXPORT int expath(const char* path, char* paths[], int nmax);
EXPORT void createdir(const char* path);

/* 定位模型 ——————————————————–*/
EXPORT double satazel(const double* pos, const double* e, double* azel);
EXPORT double geodist(const double* rs, const double* rr, double* e);
EXPORT void dops(int ns, const double* azel, double elmin, double* dop);

/* 大气模型 ———————————————————*/
EXPORT double ionmodel(gtime_t t, const double* ion, const double* pos, const double* azel);
EXPORT double ionmapf(const double* pos, const double* azel);
EXPORT double ionppp(const double* pos, const double* azel, double re, double hion, double* pppos);
EXPORT double tropmodel(gtime_t time, const double* pos, const double* azel, double humi);
EXPORT int ionocorr(gtime_t time, const nav_t* nav, int sat, const double* pos, const double* azel, int ionoopt, double* ion, double* var);
EXPORT int tropcorr(gtime_t time, const nav_t* nav, const double* pos, const double* azel, int tropopt, double* trp, double* var);

/* 天线模型 ————————————————————*/

EXPORT pcv_t* searchpcv(int sat, const char* type, gtime_t time, const pcvs_t* pcvs);
EXPORT void antmodel(const pcv_t* pcv, const double* del, const double* azel, int opt, double* dant);
EXPORT void antmodel_s(const pcv_t* pcv, double nadir, double* dant);

/* RINEX 功能 ———————————————————–*/
EXPORT int readrnx(const char* file, int rcv, const char* opt, obs_t* obs, nav_t* nav, sta_t* sta);
EXPORT int readrnxt(const char* file, int rcv, gtime_t ts, gtime_t te, double tint, const char* opt, obs_t* obs, nav_t* nav, sta_t* sta);
EXPORT int readrnxc(const char* file, nav_t* nav);
EXPORT int outrnxobsh(FILE* fp, const rnxopt_t* opt, const nav_t* nav);
EXPORT int outrnxobsb(FILE* fp, const rnxopt_t* opt, const obsd_t* obs, int n, int epflag);
EXPORT int outrnxnavh(FILE* fp, const rnxopt_t* opt, const nav_t* nav);
EXPORT int outrnxgnavh(FILE* fp, const rnxopt_t* opt, const nav_t* nav);
EXPORT int outrnxhnavh(FILE* fp, const rnxopt_t* opt, const nav_t* nav);
EXPORT int outrnxlnavh(FILE* fp, const rnxopt_t* opt, const nav_t* nav);
EXPORT int outrnxcnavh(FILE* fp, const rnxopt_t* opt, const nav_t* nav);
EXPORT int outrnxinavh(FILE* fp, const rnxopt_t* opt, const nav_t* nav);
EXPORT int outrnxnavb(FILE* fp, const rnxopt_t* opt, const eph_t* eph);
EXPORT int outrnxgnavb(FILE* fp, const rnxopt_t* opt, const geph_t* geph);
EXPORT int outrnxhnavb(FILE* fp, const rnxopt_t* opt, const seph_t* seph);
EXPORT int rtk_uncompress(const char* file, char* uncfile);;
EXPORT int init_rnxctr(rnxctr_t* rnx);
EXPORT void free_rnxctr(rnxctr_t* rnx);
EXPORT int open_rnxctr(rnxctr_t* rnx, FILE* fp);
EXPORT int input_rnxctr(rnxctr_t* rnx, FILE* fp);

/* 星历和钟差函数 ———————————————*/
EXPORT double eph2clk(gtime_t time, const eph_t* eph);
EXPORT double geph2clk(gtime_t time, const geph_t* geph);
EXPORT double seph2clk(gtime_t time, const seph_t* seph);
EXPORT void eph2pos(gtime_t time, const eph_t* eph, double* rs, double* dts, double* var);
EXPORT void geph2pos(gtime_t time, const geph_t* geph, double* rs, double* dts, double* var);
EXPORT void seph2pos(gtime_t time, const seph_t* seph, double* rs, double* dts, double* var);
EXPORT int peph2pos(gtime_t time, int sat, const nav_t* nav, int opt, double* rs, double* dts, double* var);
EXPORT void satantoff(gtime_t time, const double* rs, int sat, const nav_t* nav, double* dant);
EXPORT int satpos(gtime_t time, gtime_t teph, int sat, int ephopt, const nav_t* nav, double* rs, double* dts, double* var, int* svh);
EXPORT void satposs(gtime_t time, const obsd_t* obs, int n, const nav_t* nav, int sateph, double* rs, double* dts, double* var, int* svh);
EXPORT void setseleph(int sys, int sel);
EXPORT int getseleph(int sys);
EXPORT void alm2pos(gtime_t time, const alm_t* alm, double* rs, double* dts);

/* 接收机原始数据函数 ———————————————–*/
EXPORT uint32_t getbitu(const uint8_t* buff, int pos, int len);
EXPORT int32_t getbits(const uint8_t* buff, int pos, int len);
EXPORT void setbitu(uint8_t* buff, int pos, int len, uint32_t data);
EXPORT void setbits(uint8_t* buff, int pos, int len, int32_t data);
EXPORT uint32_t rtk_crc32(const uint8_t* buff, int len);
EXPORT uint32_t rtk_crc24q(const uint8_t* buff, int len);
EXPORT uint16_t rtk_crc16(const uint8_t* buff, int len);
EXPORT int decode_word(uint32_t word, uint8_t* data);

/* 解算函数 ——————————————————–*/
EXPORT void initsolbuf(solbuf_t* solbuf, int cyclic, int nmax);
EXPORT void freesolbuf(solbuf_t* solbuf);
EXPORT void freesolstatbuf(solstatbuf_t* solstatbuf);
EXPORT sol_t* getsol(solbuf_t* solbuf, int index);
EXPORT int addsol(solbuf_t* solbuf, const sol_t* sol);
EXPORT int readsol(char* files[], int nfile, solbuf_t* sol);
EXPORT int readsolt(char* files[], int nfile, gtime_t ts, gtime_t te, double tint, int qflag, solbuf_t* sol);
EXPORT int readsolstat(char* files[], int nfile, solstatbuf_t* statbuf);
EXPORT int readsolstatt(char* files[], int nfile, gtime_t ts, gtime_t te, double tint, solstatbuf_t* statbuf);
EXPORT int inputsol(uint8_t data, gtime_t ts, gtime_t te, double tint, int qflag, const solopt_t* opt, solbuf_t* solbuf);

EXPORT int outprcopts(uint8_t* buff, const prcopt_t* opt);
EXPORT int outsolheads(uint8_t* buff, const solopt_t* opt);
EXPORT int outsols(uint8_t* buff, const sol_t* sol, const double* rb, const solopt_t* opt);
EXPORT int outsolexs(uint8_t* buff, const sol_t* sol, const ssat_t* ssat, const solopt_t* opt);
EXPORT void outprcopt(FILE* fp, const prcopt_t* opt);
EXPORT void outsolhead(FILE* fp, const solopt_t* opt);
EXPORT void outsol(FILE* fp, const sol_t* sol, const double* rb, const solopt_t* opt);
EXPORT void outsolex(FILE* fp, const sol_t* sol, const ssat_t* ssat, const solopt_t* opt);
EXPORT int outnmea_rmc(uint8_t* buff, const sol_t* sol);
EXPORT int outnmea_gga(uint8_t* buff, const sol_t* sol);
EXPORT int outnmea_gsa(uint8_t* buff, const sol_t* sol, const ssat_t* ssat);
EXPORT int outnmea_gsv(uint8_t* buff, const sol_t* sol, const ssat_t* ssat);

/* SBAS 函数 ————————————————————*/
EXPORT int sbsreadmsg(const char* file, int sel, sbs_t* sbs);
EXPORT int sbsreadmsgt(const char* file, int sel, gtime_t ts, gtime_t te, sbs_t* sbs);
EXPORT void sbsoutmsg(FILE* fp, sbsmsg_t* sbsmsg);
EXPORT int sbsdecodemsg(gtime_t time, int prn, const uint32_t* words, sbsmsg_t* sbsmsg);
EXPORT int sbsupdatecorr(const sbsmsg_t* msg, nav_t* nav);
EXPORT int sbssatcorr(gtime_t time, int sat, const nav_t* nav, double* rs, double* dts, double* var);
EXPORT int sbsioncorr(gtime_t time, const nav_t* nav, const double* pos, const double* azel, double* delay, double* var);
EXPORT double sbstropcorr(gtime_t time, const double* pos, const double* azel, double* var);

/* 整数模糊度解算 ————————————————————*/
EXPORT int lambda(int n, int m, const double* a, const double* Q, double* F, double* s);
EXPORT int lambda_reduction(int n, const double* Q, double* Z);
EXPORT int lambda_search(int n, int m, const double* a, const double* Q, double* F, double* s);

/* 标准定位 ——————————————————*/
EXPORT int pntpos(const obsd_t* obs, int n, const nav_t* nav, const prcopt_t* opt, sol_t* sol, double* azel, ssat_t* ssat, char* msg);

/* 精确定位 ——————————————————-*/
EXPORT void rtkinit(rtk_t* rtk, const prcopt_t* opt);
EXPORT void rtkfree(rtk_t* rtk);
EXPORT int rtkpos(rtk_t* rtk, const obsd_t* obs, int nobs, const nav_t* nav);
EXPORT int rtkopenstat(const char* file, int level);
EXPORT void rtkclosestat(void);
EXPORT int rtkoutstat(rtk_t* rtk, char* buff);

/* 后处理定位 —————————————————————*/
EXPORT int postpos(gtime_t ts, gtime_t te, double ti, double tu, const prcopt_t* popt, const solopt_t* sopt, const filopt_t* fopt, char** infile, int n, char* outfile, const char* rov, const char* base);

/* 应用程序定义的函数 ———————————————*/
extern int showmsg(const char* format, …);
extern void settspan(gtime_t ts, gtime_t te);
extern void settime(gtime_t time);

#ifdef __cplusplus
}
#endif
#endif /* DGNSS_H */