RTK 实时动态定位
RTK 技术深度解析
载波相位测量
RTK 的核心是载波相位测量,比伪距测量精度高 100 倍:
伪距测量:
精度:约 1-3m(码相关,码片宽度约 300m)
载波相位测量:
GPS L1 波长:λ = c/f = 3×10⁸ / 1575.42×10⁶ ≈ 19cm
相位测量精度:约 1-2mm(波长的 1/100)
但存在整周模糊度(Integer Ambiguity):
φ = N × λ + 小数部分
N 是未知整数(整周数)
RTK 的关键:快速确定整周模糊度 N(整周模糊度固定)
固定后精度:1-2cm
未固定(浮点解):10-50cm差分改正原理
基准站误差模型:
ε_ref = 电离层误差 + 对流层误差 + 星历误差 + 时钟误差
基准站知道精确位置,可以计算出 ε_ref
流动站应用改正:
ε_rover ≈ ε_ref(距离 < 50km 时,误差高度相关)
流动站精确位置 = 流动站观测 - ε_ref
双差(Double Difference)消除误差:
卫星间差分:消除接收机时钟误差
站间差分:消除卫星时钟误差
双差 = 站间差分 - 卫星间差分
→ 消除大部分系统误差RTCM 差分数据格式
RTK 改正数使用 RTCM(Radio Technical Commission for Maritime Services)格式传输:
常用 RTCM 消息类型
| 消息类型 | 内容 | 说明 |
|---|---|---|
| RTCM 1001-1004 | GPS 观测数据 | 伪距和载波相位 |
| RTCM 1005/1006 | 基准站坐标 | 基准站精确位置 |
| RTCM 1007/1008 | 天线描述 | 天线类型和高度 |
| RTCM 1009-1012 | GLONASS 观测数据 | |
| RTCM 1033 | 接收机描述 | |
| RTCM 1074-1077 | GPS MSM | 多信号消息(推荐) |
| RTCM 1084-1087 | GLONASS MSM | |
| RTCM 1094-1097 | Galileo MSM | |
| RTCM 1124-1127 | BeiDou MSM |
推荐 RTCM 配置
基准站输出(推荐):
RTCM 1005:基准站坐标(1Hz)
RTCM 1077:GPS MSM7(1Hz)
RTCM 1087:GLONASS MSM7(1Hz)
RTCM 1097:Galileo MSM7(1Hz)
RTCM 1127:BeiDou MSM7(1Hz)
MSM7 包含完整的伪距、载波相位、多普勒、信噪比数据网络 RTK(CORS 网络)
虚拟参考站(VRS)
CORS 网络通过多个基准站构建虚拟参考站,用户无需自建基准站:
CORS 网络架构:
多个基准站(间距 50-100km)
↓
数据中心(计算 VRS 改正数)
↓
NTRIP Caster(分发改正数)
↓
流动站(通过互联网接收)
VRS 工作原理:
1. 流动站发送概略位置(GGA)给 NTRIP Caster
2. 数据中心在流动站附近生成虚拟基准站
3. 流动站接收虚拟基准站的改正数
4. 精度与真实基准站相当(< 1km 距离)国内 CORS 服务
| 服务商 | 覆盖范围 | 精度 | 费用 |
|---|---|---|---|
| 千寻位置(FindCM) | 全国 | 1-2cm | 商业收费 |
| 华测导航 | 全国 | 1-2cm | 商业收费 |
| 各省测绘局 CORS | 省内 | 1-3cm | 政府/收费 |
| 北斗地基增强系统 | 全国 | 1-3cm | 政府服务 |
移远模组 RTK 开发
LC79D 快速上手
bash
# 1. 硬件连接
# UART1:NMEA 数据输出(定位结果)
# UART2:RTCM 数据输入(差分改正数)
# 波特率:115200(默认)
# 2. 配置输出频率(通过 UBX 协议)
# 使用 u-center 软件配置,或发送 UBX 命令
# 3. 通过 AT 指令(集成在蜂窝模组时)
AT+QGPSCFG="outport","usbnmea" # 设置 NMEA 输出端口
AT+QGPS=1 # 启动 GNSS
AT+QGPSLOC? # 查询位置
# 4. 注入 RTCM 数据
# 将 NTRIP 客户端获取的 RTCM 数据发送到 UART2
# 或通过 AT 指令注入
AT+QGPSRTK=<rtcm_data_hex>Python 示例:NTRIP 客户端
python
import socket
import base64
import serial
import threading
class NTRIPClient:
def __init__(self, host, port, mountpoint, username, password):
self.host = host
self.port = port
self.mountpoint = mountpoint
self.auth = base64.b64encode(
f"{username}:{password}".encode()
).decode()
self.sock = None
def connect(self, rover_lat, rover_lon):
"""连接 NTRIP Caster"""
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((self.host, self.port))
# 发送 HTTP 请求
request = (
f"GET /{self.mountpoint} HTTP/1.0\r\n"
f"Host: {self.host}\r\n"
f"Ntrip-Version: Ntrip/2.0\r\n"
f"User-Agent: NTRIP QuectelClient/1.0\r\n"
f"Authorization: Basic {self.auth}\r\n"
f"Ntrip-GGA: {self._build_gga(rover_lat, rover_lon)}\r\n"
f"\r\n"
)
self.sock.send(request.encode())
# 读取响应头
response = b""
while b"\r\n\r\n" not in response:
response += self.sock.recv(1024)
if b"200 OK" in response or b"ICY 200 OK" in response:
print("NTRIP 连接成功")
return True
else:
print("NTRIP 连接失败:", response[:200])
return False
def stream_to_gnss(self, gnss_serial_port):
"""将 RTCM 数据流转发到 GNSS 模组"""
ser = serial.Serial(gnss_serial_port, 115200)
while True:
data = self.sock.recv(4096)
if not data:
break
# 将 RTCM 数据写入 GNSS 模组的 UART
ser.write(data)
def _build_gga(self, lat, lon):
"""构建 GGA 语句(发送给 NTRIP Caster 的概略位置)"""
lat_deg = int(lat)
lat_min = (lat - lat_deg) * 60
lon_deg = int(lon)
lon_min = (lon - lon_deg) * 60
return (f"$GPGGA,000000.00,"
f"{lat_deg:02d}{lat_min:07.4f},N,"
f"{lon_deg:03d}{lon_min:07.4f},E,"
f"1,08,1.0,0.0,M,0.0,M,,*00")
# 使用示例
client = NTRIPClient(
host="rtk.ntrip.com",
port=2101,
mountpoint="RTCM32_GGB",
username="your_username",
password="your_password"
)
if client.connect(31.2304, 121.4737): # 上海概略位置
client.stream_to_gnss("/dev/ttyUSB1")RTK 性能优化
提高整周模糊度固定率
影响固定率的因素:
1. 信号质量(GNSS 信号强度)
→ 使用高增益天线,避免遮挡
2. 基线长度(流动站到基准站距离)
→ 距离越近,误差相关性越高,固定越快
→ 建议 < 30km(单频),< 100km(双频)
3. 卫星数量
→ 多星座(GPS+GLONASS+BeiDou+Galileo)
→ 双频(L1+L2 或 L1+L5)
4. 多路径效应
→ 天线安装在开阔位置
→ 使用扼流圈天线
5. 电离层活动
→ 太阳活动高峰期,固定率下降
→ 使用双频可以消除电离层误差