精准定位
功能说明
RTK Precise Position 功能用于将 DJI PSDK 订阅到的 RTK 定位、速度、航向和解状态转换为 MAVLink 标准定位消息输出。
本功能只负责“PSDK RTK 数据 -> MAVLink 定位消息”的转换,不负责启动网络 RTK 服务。网络 RTK 服务的账号、NTRIP 配置和启停请参考 network_rtk.md。
相关文件
| 文件 | 说明 |
|---|---|
src/dji_function/dji_sub_callback.cpp |
RTK 订阅、坐标转换、MAVLink 定位消息发送 |
src/dji_mavlink/mavlink_tool.h |
MAVLink 工具函数、坐标/角度转换函数 |
PSDK 订阅 Topic
| PSDK Topic | 频率 | 用途 |
|---|---|---|
DJI_FC_SUBSCRIPTION_TOPIC_RTK_POSITION |
5 Hz | RTK 经纬度和高程 |
DJI_FC_SUBSCRIPTION_TOPIC_RTK_VELOCITY |
5 Hz | RTK 速度 |
DJI_FC_SUBSCRIPTION_TOPIC_RTK_YAW |
5 Hz | RTK 双天线航向 |
DJI_FC_SUBSCRIPTION_TOPIC_RTK_POSITION_INFO |
5 Hz | RTK 定位解状态 |
DJI_FC_SUBSCRIPTION_TOPIC_RTK_YAW_INFO |
5 Hz | RTK 航向解状态 |
DJI_FC_SUBSCRIPTION_TOPIC_RTK_CONNECT_STATUS |
5 Hz | RTK 连接状态 |
输出 MAVLink 消息
| MAVLink 消息 | 说明 |
|---|---|
GPS_RAW_INT |
主 GPS/RTK 定位输出 |
GPS2_RAW |
第二路 GPS/RTK 定位输出,内容与 RTK 主定位一致 |
GPS_INPUT |
给飞控/上位机使用的 GPS 输入格式 |
GLOBAL_POSITION_INT |
全局位置、相对高度、速度和航向 |
GPS_RTK |
主 RTK 状态 |
GPS2_RTK |
第二路 RTK 状态 |
坐标系和单位
坐标系转换必须保持以下规则,避免 MAVLink 侧坐标混乱。
| 数据 | DJI/PSDK 来源 | MAVLink 输出 | 转换说明 |
|---|---|---|---|
| 纬度 | RTK_POSITION.latitude,单位 degree |
lat,单位 degE7 |
degree * 1e7 |
| 经度 | RTK_POSITION.longitude,单位 degree |
lon,单位 degE7 |
degree * 1e7 |
| 高程 | RTK_POSITION.hfsl,单位 m |
alt,单位 mm |
m * 1000 |
| 北向速度 | RTK_VELOCITY.x |
vn / vx |
保持 North 方向 |
| 东向速度 | RTK_VELOCITY.y |
ve / vy |
保持 East 方向 |
| 垂向速度 | RTK_VELOCITY.z |
vd / vz |
MAVLink NED 使用 Down,输出时取负 |
| RTK 航向 | RTK_YAW |
yaw / hdg,单位 cdeg |
DJI RTK yaw 为 ANT1->ANT2,输出前减 90 deg |
航向转换
DJI RTK 双天线 yaw 与 MAVLink 车辆航向存在 90 度偏移,代码中统一使用:
mavlink_yaw_deg = dji_rtk_yaw_deg - 90
mavlink_yaw_cdeg = normalize_0_360(mavlink_yaw_deg) * 100当结果为 0 deg 时,GPS_RAW_INT.yaw 按 MAVLink 约定输出 36000;当航向不可用时输出 UINT16_MAX。
定位解状态映射
| DJI RTK 解状态 | MAVLink fix_type |
|---|---|
| 窄巷固定解、宽巷固定解、L1 整周模糊度固定解 | GPS_FIX_TYPE_RTK_FIXED |
| 浮点解、L1 浮点解、无电离层组合浮点解 | GPS_FIX_TYPE_RTK_FLOAT |
| 单点解、伪距差分解、SBAS 解 | GPS_FIX_TYPE_3D_FIX |
| 其他/未知 | GPS_FIX_TYPE_NO_FIX |
数据输出策略
RTK 定位有效时,系统优先输出 RTK 定位数据,并临时抑制普通 GPS 位置回调中的低精度 GPS_RAW_INT / GLOBAL_POSITION_INT 输出。
RTK 定位无效或超过 1 秒未更新时,普通 GPS 输出恢复,避免上位机长时间没有定位消息。
使用流程
- 启动程序后,订阅模块自动订阅 RTK 相关 Topic。
- 上位机监听标准 MAVLink 定位消息。
- 当 RTK 进入 Float 或 Fixed 解时,
GPS_RAW_INT.fix_type变为GPS_FIX_TYPE_RTK_FLOAT或GPS_FIX_TYPE_RTK_FIXED。 - 如需网络 RTK 数据源,先通过
network_rtk.md中的 Network RTK 功能配置并启动 NTRIP 服务。
Python 例程
以下例程使用 pymavlink 监听 RTK 精准定位相关 MAVLink 消息,并打印经纬度、高度、速度、航向和 RTK 解状态。
import time
from pymavlink import mavutil
def get_current_millis():
return int(time.time() * 1000)
def fix_type_name(fix_type):
names = {
0: "NO_GPS",
1: "NO_FIX",
2: "2D_FIX",
3: "3D_FIX",
4: "DGPS",
5: "RTK_FLOAT",
6: "RTK_FIXED",
}
return names.get(fix_type, f"UNKNOWN({fix_type})")
def yaw_cdeg_to_deg(yaw):
if yaw == 65535:
return None
if yaw == 36000:
return 0.0
return yaw / 100.0
# 连接无人机(UDP 端口 14550)
master = mavutil.mavlink_connection("udpin:0.0.0.0:14550")
print("等待无人机心跳...")
master.wait_heartbeat()
print(f"无人机已连接: system={master.target_system}, component={master.target_component}")
print("开始监听 RTK 精准定位消息")
message_types = [
"GPS_RAW_INT",
"GPS2_RAW",
"GPS_INPUT",
"GLOBAL_POSITION_INT",
"GPS_RTK",
"GPS2_RTK",
]
while True:
msg = master.recv_match(type=message_types, blocking=True, timeout=5.0)
now_ms = get_current_millis()
if msg is None:
print(f"[{now_ms}] 超时:未收到 RTK/MAVLink 定位消息")
continue
msg_type = msg.get_type()
if msg_type in ("GPS_RAW_INT", "GPS2_RAW"):
lat_deg = msg.lat / 1e7
lon_deg = msg.lon / 1e7
alt_m = msg.alt / 1000.0
yaw_deg = yaw_cdeg_to_deg(getattr(msg, "yaw", 65535))
print(
f"[{now_ms}] {msg_type}: "
f"fix={fix_type_name(msg.fix_type)}, "
f"lat={lat_deg:.7f}, lon={lon_deg:.7f}, alt={alt_m:.3f}m, "
f"vel={msg.vel / 100.0:.2f}m/s, cog={msg.cog / 100.0:.2f}deg, "
f"yaw={yaw_deg}"
)
elif msg_type == "GPS_INPUT":
print(
f"[{now_ms}] GPS_INPUT: "
f"fix={fix_type_name(msg.fix_type)}, "
f"lat={msg.lat / 1e7:.7f}, lon={msg.lon / 1e7:.7f}, alt={msg.alt:.3f}m, "
f"vn={msg.vn:.2f}, ve={msg.ve:.2f}, vd={msg.vd:.2f}"
)
elif msg_type == "GLOBAL_POSITION_INT":
print(
f"[{now_ms}] GLOBAL_POSITION_INT: "
f"lat={msg.lat / 1e7:.7f}, lon={msg.lon / 1e7:.7f}, "
f"alt={msg.alt / 1000.0:.3f}m, relative_alt={msg.relative_alt / 1000.0:.3f}m, "
f"vx={msg.vx / 100.0:.2f}, vy={msg.vy / 100.0:.2f}, vz={msg.vz / 100.0:.2f}, "
f"hdg={msg.hdg / 100.0:.2f}deg"
)
elif msg_type in ("GPS_RTK", "GPS2_RTK"):
print(
f"[{now_ms}] {msg_type}: "
f"health={msg.rtk_health}, rate={msg.rtk_rate}Hz, nsats={msg.nsats}, "
f"receiver_id={msg.rtk_receiver_id}"
)注意事项
- MAVLink
GLOBAL_POSITION_INT的速度字段为 NED 坐标系,垂向速度必须使用 Down 为正。 - RTK 服务状态等于
DJI_TRANSFER只代表 RTCM/网络数据传输建立,不等于 RTK 已经收敛。是否可用必须看 RTK 定位解状态。 GPS_RTK/GPS2_RTK中没有 DJI 可直接提供的基线详细值时,对应字段使用未知值或 0 填充。- 如果地面站只看
GPS_RAW_INT,需要确认其支持GPS_FIX_TYPE_RTK_FLOAT和GPS_FIX_TYPE_RTK_FIXED。
作者:bai 创建时间:2026-06-23 14:18
最后编辑:bai 更新时间:2026-07-08 09:44
最后编辑:bai 更新时间:2026-07-08 09:44