RTK模组调试
2026/9/10 13:29:05 网站建设 项目流程

最近有项目需要用高精度定位模组,原来用的普通北斗定位模组换成了高精度RTK模组,也是第一次使用,现在把调试过程记录下。

一、RTK工作原理

RTK工作原理:

将基站放置通过精确测量的位置且无GNSS信号遮挡,以确保能够连续接收所有可见的GNSS卫 星信号。
基站通过可靠的数据链路(网络、无线电等)向移动站发送其坐标和修正数据。
移动站接收来自基站的数据,并同步观测和收集GNSS卫星的载波相位数据。
移动站根据从卫星接收到的载波相位数据和从基站接收到的修正数据计算出精确的位置。
RTK通常可分为:
传统RTK:差分改正数据的传输链路通常由无线电台来提供,且基站和移动站之间的距离一般在 20~30 km 以内。因为其形成的测量偏差与距离有关,超过这个距离,则会造成移动站的定位精度 大幅度下降。
网络RTK:通过联合多基站的数据进行误差计算、改正,向用户提供空间位置服务的一种实时定 位技术,需要通过网络实现系统中心对多基准站的数据共享。网络 RTK技术克服了传统RTK技 术定位精度与距离相关性强、作业时需频繁架设基准站等缺点。

传统RTK技术与网络RTK技术:

在传统RTK技术服务模型中,改正数据的传输链路通常由无线电台来提供,且基站和移动站之间的距离一般在 30 km以内。由于移动站与基站距离不同,这就导致轨道偏差、电离层偏差和对流层偏差会有所 不同。超过这个距离,移动站的定位精度将大幅度下降。
为了突破这种单基站的传统 RTK技术的局限性,网络RTK技术应运而生。网络RTK技术是联合多基 站的数据进行误差计算、改正,向用户提供空间位置服务的一种实时定位技术,需要通过网络实现系统中 心对多基站数据共享。网络 RTK技术克服了传统RTK技术作业范围小、定位精度与距离相关性强、作业 时需频繁架设基站等缺点。
目前,网络RTK最常见的方法是VRS(虚拟参考站)。在这种情况下,移动站以标准的NMEA0183 GGA 消息格式将位置发送给网络数据处理中心,网络数据处理中心将在移动站附近创建一个 VRS,并计算出一 组对应的改正数据,然后发送回移动站,移动站再计算出高精度位置。

网络RTK的特点:

通常情况,网络RTK有如下特点:
优点
1.精度不再受地域限制。随着CORS网络的建设,可以在大部分地区获得高精度的定位坐标。
2.无需单独部署基站,不仅节省了运营成本,也在一定程度上提高了工作效率。
3.快速实现高精度定位,集成服务商提供的SDK,可以快速实现秒级的固定收敛。
缺点
对无线数据网络的覆盖有强依赖。网络RTK需要通过无线数据网络来传输改正数据,无网络覆盖的地 区无法使用网络 RTK
通过以上,我们知道,要使用RTK,需要系统能从RTK服务器获得差分修正数据,然后传给RTK模组,这样就可以到的高精度坐标。

二、RTKNTRIP

为了实现RTK的高精度定位效果,需要向GNSS移动站连续注入基站的改正数据,通常情况下是通过 因特网,传输协议为 NTRIP
NTRIP是一个应用进程级协议,它支持通过因特网流式传输全球导航卫星系统(GNSS)数据。NTRIP 是一个基于超文本传输协议(HTTP)的通用无状态协议。使用NTRIP协议发送GNSS数据流,主要包括RTCM 数据格式的数据流和NMEA格式的GGA数据流,以及其他格式的GNSS数据流。
NTRIP支持通过以下方式上网:
移动IP网络,如GSMGPRSEDGEUMTSLTE5G
Wi-Fi网络
有线IP网络
NTRIP系统的组成:
NTRIP协议目前有两个版本,分别为NTRIP v1.0NTRIP v2.0。主要区别为数据传输格式上,v2.0 版本更加严格地遵循了标准 HTTP协议规范;详细具体差异,可参考RTCM104系列的规范文档。考虑目前实际应用过程中大部分使用的是 v1.0版本的协议,因此以下介绍默认参考NTRIP v1.0版本。

NtripSource:生成特定位置的改正数据流,并把此改正数据提交给NtripServer
NtripServer:负责把改正数据提交给NtripCaster
NtripCaster:数据分发中心,负责接收、转发GNSS数据流。
NtripClient:登录NtripCaster后,NtripCaster把特定位置的改正数据发送给它。
NtripSourceNtripServer一般已经集成到一台GNSS基站内,基站产生当前特定位置的改正数据,然后再通过网络发送给 NtripCaster。NtripCaster 一般就是一台服务器,它负责接收、转发GNSS数据数据流。通常NtripCaster有两种工 作形式:
依据不同的挂载点,直接将对应的基站的改正数据发送给移动站。
先通过算法将多个实际的基站虚拟成一个最为匹配移动站的虚拟参考站(VRS)。然后将改正数据 发送给移动站。
NtripClient一般就是GNSS移动站。移动站登录NtripCaster后,发送自身的坐标给NtripCaster。NtripCaster 选择或产生特定位置的改正数据,然后发送给NtripClient。这样在GNSS移动站即可实现RTK 的高精度定位。
通过以上,我知道了,系统必须创建一个TCP链接,然后在TCP上面建立HTTP客户端,登入并发送坐标数据,等待服务器返回差分数据。

三、RTCM3协议

RTK服务器返回的数据是RTCM3协议数据,格式是HEX格式。

字段

比特

说明

Preamble 前导码

8bit

固定 0xD3,帧起始标志

Reserved 保留位

6bit

默认填 0

Message Length 消息长度

10bit

载荷 Data 字段字节数,最大 1023 字节

Data 数据载荷

N×8bit

变长,内部第一个 12bit 是消息类型号

CRC24Q 校验

24bit(3 字节)

校验范围:前导码 + 保留 + 长度 + Data 载荷,不包含自身 CRC3 字节

整帧总字节 =3 字节头 + N 字节载荷 +3 字节 CRC总帧最小 6 字节,最大:3+1023+3 =1029 字节

[0xD3][Resv+Len(2B)][Data(N字节)][CRC24Q(3B)]

Data 载荷内部开头

Data 最开始12bit = Message Type 消息号,例如 1005、1074、1124 等。

⚠️TCP 是字节流,会粘包、拆包;不能按固定长度读取,必须写状态机循环扫描 0xD3 同步头,取出完整帧,做 CRC24Q 校验,校验成功才解析,失败丢弃

计算法:

uint32_t rtcm_crc24q(const uint8_t *data, size_t len) { const uint32_t POLY = 0x1864CFB; // CRC-24Q 多项式 uint32_t crc = 0; size_t i, j; for (i = 0; i < len; i++) { crc ^= ((uint32_t)data[i]) << 16; // 字节与CRC高8位异或 for (j = 0; j < 8; j++) { crc <<= 1; // 左移一位 if (crc & 0x01000000) { // 检查最高位(第24位) crc ^= POLY; // 异或多项式 } } } return crc & 0x00FFFFFF; // 只保留低24位 }

查表法:

const uint32_t wCrc24qTable[] = { 0x00000000,0x00864CFB,0x008AD50D,0x000C99F6, 0x0093E6E1,0x0015AA1A,0x001933EC,0x009F7F17, 0x00A18139,0x0027CDC2,0x002B5434,0x00AD18CF, 0x003267D8,0x00B42B23,0x00B8B2D5,0x003EFE2E, 0x00C54E89,0x00430272,0x004F9B84,0x00C9D77F, 0x0056A868,0x00D0E493,0x00DC7D65,0x005A319E, 0x0064CFB0,0x00E2834B,0x00EE1ABD,0x00685646, 0x00F72951,0x007165AA,0x007DFC5C,0x00FBB0A7, 0x000CD1E9,0x008A9D12,0x008604E4,0x0000481F, 0x009F3708,0x00197BF3,0x0015E205,0x0093AEFE, 0x00AD50D0,0x002B1C2B,0x002785DD,0x00A1C926, 0x003EB631,0x00B8FACA,0x00B4633C,0x00322FC7, 0x00C99F60,0x004FD39B,0x00434A6D,0x00C50696, 0x005A7981,0x00DC357A,0x00D0AC8C,0x0056E077, 0x00681E59,0x00EE52A2,0x00E2CB54,0x006487AF, 0x00FBF8B8,0x007DB443,0x00712DB5,0x00F7614E, 0x0019A3D2,0x009FEF29,0x009376DF,0x00153A24, 0x008A4533,0x000C09C8,0x0000903E,0x0086DCC5, 0x00B822EB,0x003E6E10,0x0032F7E6,0x00B4BB1D, 0x002BC40A,0x00AD88F1,0x00A11107,0x00275DFC, 0x00DCED5B,0x005AA1A0,0x00563856,0x00D074AD, 0x004F0BBA,0x00C94741,0x00C5DEB7,0x0043924C, 0x007D6C62,0x00FB2099,0x00F7B96F,0x0071F594, 0x00EE8A83,0x0068C678,0x00645F8E,0x00E21375, 0x0015723B,0x00933EC0,0x009FA736,0x0019EBCD, 0x008694DA,0x0000D821,0x000C41D7,0x008A0D2C, 0x00B4F302,0x0032BFF9,0x003E260F,0x00B86AF4, 0x002715E3,0x00A15918,0x00ADC0EE,0x002B8C15, 0x00D03CB2,0x00567049,0x005AE9BF,0x00DCA544, 0x0043DA53,0x00C596A8,0x00C90F5E,0x004F43A5, 0x0071BD8B,0x00F7F170,0x00FB6886,0x007D247D, 0x00E25B6A,0x00641791,0x00688E67,0x00EEC29C, 0x003347A4,0x00B50B5F,0x00B992A9,0x003FDE52, 0x00A0A145,0x0026EDBE,0x002A7448,0x00AC38B3, 0x0092C69D,0x00148A66,0x00181390,0x009E5F6B, 0x0001207C,0x00876C87,0x008BF571,0x000DB98A, 0x00F6092D,0x007045D6,0x007CDC20,0x00FA90DB, 0x0065EFCC,0x00E3A337,0x00EF3AC1,0x0069763A, 0x00578814,0x00D1C4EF,0x00DD5D19,0x005B11E2, 0x00C46EF5,0x0042220E,0x004EBBF8,0x00C8F703, 0x003F964D,0x00B9DAB6,0x00B54340,0x00330FBB, 0x00AC70AC,0x002A3C57,0x0026A5A1,0x00A0E95A, 0x009E1774,0x00185B8F,0x0014C279,0x00928E82, 0x000DF195,0x008BBD6E,0x00872498,0x00016863, 0x00FAD8C4,0x007C943F,0x00700DC9,0x00F64132, 0x00693E25,0x00EF72DE,0x00E3EB28,0x0065A7D3, 0x005B59FD,0x00DD1506,0x00D18CF0,0x0057C00B, 0x00C8BF1C,0x004EF3E7,0x00426A11,0x00C426EA, 0x002AE476,0x00ACA88D,0x00A0317B,0x00267D80, 0x00B90297,0x003F4E6C,0x0033D79A,0x00B59B61, 0x008B654F,0x000D29B4,0x0001B042,0x0087FCB9, 0x001883AE,0x009ECF55,0x009256A3,0x00141A58, 0x00EFAAFF,0x0069E604,0x00657FF2,0x00E33309, 0x007C4C1E,0x00FA00E5,0x00F69913,0x0070D5E8, 0x004E2BC6,0x00C8673D,0x00C4FECB,0x0042B230, 0x00DDCD27,0x005B81DC,0x0057182A,0x00D154D1, 0x0026359F,0x00A07964,0x00ACE092,0x002AAC69, 0x00B5D37E,0x00339F85,0x003F0673,0x00B94A88, 0x0087B4A6,0x0001F85D,0x000D61AB,0x008B2D50, 0x00145247,0x00921EBC,0x009E874A,0x0018CBB1, 0x00E37B16,0x006537ED,0x0069AE1B,0x00EFE2E0, 0x00709DF7,0x00F6D10C,0x00FA48FA,0x007C0401, 0x0042FA2F,0x00C4B6D4,0x00C82F22,0x004E63D9, 0x00D11CCE,0x00575035,0x005BC9C3,0x00DD8538, }; /** * 查表法核心实现 * * 算法原理: * crc = (crc << 8) ^ table[((crc >> 16) ^ data[i]) & 0xFF] * * 其中: * - (crc >> 16): 取出CRC高8位 * - ^ data[i]: 与当前字节异或 * - & 0xFF: 取低8位作为表索引 * - table[index]: 预计算好的CRC增量 * - crc << 8: CRC左移8位 * - ^ table[index]: 异或增量 */ uint32_t rtcm_crc24q_table(const uint8_t *data, size_t len) { // 确保表已初始化 // if (!table_initialized) { // rtcm_crc24q_init_table(); // } uint32_t crc = 0; for (size_t i = 0; i < len; i++) { uint8_t index = (uint8_t)(((crc >> 16) ^ data[i]) & 0xFF); crc = (crc << 8) ^ wCrc24qTable[index]; crc &= 0x00FFFFFF; // 保持24位 } return crc; }

四、嵌入式开发流程

RTK服务器可以选用千寻位置、中移定位、六分科技等,需要花钱购买账号。这里以千寻位置为例,其他类似。

IP网址和端口号:rtk.ntrip.qxwz.com:8003,这里选择8003

挂载点有两个:AUTO(五星十六频);RTCM32_GGB(三星八频),这里选择AUTO

千寻位置账号使用有两种方式:SDK和差分账号。SDK需要提供编译信息向官方申请,这里选用差分账号。

HTTP链接登入格式:

GET /{MountPoint} HTTP/1.0
User-Agent: NTRIP ClientName/Version
Authorization: Basic {Base64EncodedCredentials}
Ntrip-Version: Ntrip/2.0
Connection: close
Ntrip-GGA: {GPGGA_Sentence} // 可选,用于发送移动端位置
字段 说明
MountPoint 挂载点名称(如RTCM32_GGB),标识特定数据流
User-Agent 客户端标识(需符合NTRIP规范,如NTRIP RTKLIB/1.0)
Authorization Basic认证(格式:Basic base64(user:password))
Ntrip-Version 协议版本声明(v2.0必须包含此头)
Ntrip-GGA 可选的NMEA GGA语句,用于向服务器报告客户端位置

认证格式为user:password,然后用 base64格式化:

static const char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // **Base64 编码实现** uint16_t base64_encode(unsigned char* pchOutput, uint16_t hwOutputBufferSize,const unsigned char* c_pchInput, uint16_t hwInputLen) { uint16_t output_len = 4 * ((hwInputLen + 2) / 3); // 计算输出长度 //char* output = (char*)malloc(output_len + 1); // 为输出分配内存 if(NULL == pchOutput || !hwOutputBufferSize || NULL == c_pchInput || !hwInputLen){ return 0; } if(output_len+1 > hwOutputBufferSize){ return 0; } //if (!pchOutput) return 0; // 内存分配失败 uint16_t i, j; for (i = 0, j = 0; i < hwInputLen;) { uint32_t octet_a = i < hwInputLen ? c_pchInput[i++] : 0; uint32_t octet_b = i < hwInputLen ? c_pchInput[i++] : 0; uint32_t octet_c = i < hwInputLen ? c_pchInput[i++] : 0; uint32_t combined = (octet_a << 16) | (octet_b << 8) | octet_c; pchOutput[j++] = base64_table[(combined >> 18) & 0x3F]; pchOutput[j++] = base64_table[(combined >> 12) & 0x3F]; pchOutput[j++] = i > hwInputLen + 1 ? '=' : base64_table[(combined >> 6) & 0x3F]; pchOutput[j++] = i > hwInputLen ? '=' : base64_table[combined & 0x3F]; } pchOutput[output_len] = '\0'; // 添加 NULL 终止符 return output_len; } // **Base64 解码实现** uint16_t base64_decode(unsigned char* pchOutput,uint16_t hwOutputBufferSize,const char* c_pcInput) { uint16_t hwOutputLen = 0; uint16_t hwInputLen = 0; if(NULL == pchOutput || !hwOutputBufferSize || NULL == c_pcInput){ return 0; } hwInputLen = strlen(c_pcInput); if (hwInputLen % 4 != 0) return 0; // 输入长度必须是4的倍数 hwOutputLen = hwInputLen / 4 * 3; if (c_pcInput[hwInputLen - 1] == '=') (hwOutputLen)--; if (c_pcInput[hwInputLen - 2] == '=') (hwOutputLen)--; if(hwOutputLen +1 > hwOutputBufferSize){ return 0; } //unsigned char* output = (unsigned char*)malloc(*output_len + 1); // 分配额外空间以存储 NULL 终止符 //if (!pchOutput) return 0; size_t i, j; for (i = 0, j = 0; i < hwInputLen;) { int sextet_a = c_pcInput[i] == '=' ? 0 : strchr(base64_table, c_pcInput[i++]) - base64_table; int sextet_b = c_pcInput[i] == '=' ? 0 : strchr(base64_table, c_pcInput[i++]) - base64_table; int sextet_c = c_pcInput[i] == '=' ? 0 : strchr(base64_table, c_pcInput[i++]) - base64_table; int sextet_d = c_pcInput[i] == '=' ? 0 : strchr(base64_table, c_pcInput[i++]) - base64_table; uint32_t combined = (sextet_a << 18) | (sextet_b << 12) | (sextet_c << 6) | sextet_d; if (j < hwOutputLen) pchOutput[j++] = (combined >> 16) & 0xFF; if (j < hwOutputLen) pchOutput[j++] = (combined >> 8) & 0xFF; if (j < hwOutputLen) pchOutput[j++] = combined & 0xFF; } pchOutput[hwOutputLen] = '\0'; // 添加 NULL 终止符 return hwOutputLen; }

登入流程如下:

1、获取RTK模组的GGA信息:如

$GNGGA,071516.000,3149.301159,N,11706.919870,E,1,16,0.95,70.2,M,-0.3,M,,*59

2、设备登入RTK服务器

(1)TCP登入:rtk.ntrip.qxwz.com:8003

(2)发送HTTP登入帧:

返回:ICY 200 OK,说明登入成功。

(注意:发送帧后面要跟两个回车换行符)

(3)设备直接发送GGA信息给RTK服务器,得到差分数据,转发给RTK模组即可。

$GNGGA,071516.000,3149.301159,N,11706.919870,E,1,16,0.95,70.2,M,-0.3,M,,*59\r\n\r\n

(注意:发送帧后面要跟两个回车换行符)

(4)等到二进制RTCM3数据。

(5)RTK模组成功后:

2026.08.25

今天测试RTK模组,用官方提供的软件可以成功,用自己搭建的测试环境,始终不行。分析原因,是自己搭建的环境只是把RTK服务器的一帧数据返回给了模组,应该是把模组没秒的GGA数据给RTK服务器,然后把服务器每秒返回的数据给模组,让模组不停地修正,这样才能进入RTK模组。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询