Skip to content

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-1004GPS 观测数据伪距和载波相位
RTCM 1005/1006基准站坐标基准站精确位置
RTCM 1007/1008天线描述天线类型和高度
RTCM 1009-1012GLONASS 观测数据
RTCM 1033接收机描述
RTCM 1074-1077GPS MSM多信号消息(推荐)
RTCM 1084-1087GLONASS MSM
RTCM 1094-1097Galileo MSM
RTCM 1124-1127BeiDou 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. 电离层活动
   → 太阳活动高峰期,固定率下降
   → 使用双频可以消除电离层误差

褚成志的笔记