这两年我接过不少定位相关的项目,最有感触的倒不是单台设备怎么把 RTK 调到固定解,而是当车辆数量从几台变成几十台时,整个事情的复杂度会瞬间爆炸。Point One Navigation 这次更新的点,恰好是把赛道从“设备级”拉到了“车队级”——开发者可以像调用普通云 API 一样,一次性把整个车队的精确定位策略部署下去,不用再一台一台配差分账号、导证书、查挂载点。这篇文章会把车队级定位的思路、新特性在接口层解决的核心问题,以及实际接入时的经验和坑完整整理出来,给正在做自动驾驶、无人物流、移动机器人和精准农业定位的同学做个参考。
1. 先从团队视角理解这次升级:为什么车队级定位是刚需
1.1 单机调试和 Fleet 管理的根本差异
如果你只负责一台机器人或者一辆车,把 RTK 跑固定其实是个很简单的活:装好天线,接入一个 NTRIP 挂载点,看原始报文,调整杆臂参数,半小时就能搞明白。麻烦的是规模化。当车辆数量到十几台、几十台的时候,真正卡住你的根本不是定位算法,而是分发、账号和运维。
每一台设备都要有独立的差分服务标识,每台车的网络策略、精度要求和运营区域可能都不同。设备分布在不同城市,又涉及基站网络选择。传统做法是服务商提供一个云后台,你可以逐台添加设备,但是效率很低——你得手工给 A 车加一个账号,给 B 车生成另一张证书,如果某台设备换了 4G 模块,又要重新注册。整个流程是设备维度的,不是业务维度的。
Point One 这次的新特性,从产品设计上把管理维度切到了 fleet:先把整个车队作为一个逻辑对象,为它定义统一的策略和覆盖要求,然后由平台自动去分配挂在车队下的各台设备。这个思路其实和云端服务器集群管理有点像——你管理的对象是一组服务,而不是一台台的机器,底层调度交给平台去做。
1.2 新特性把“接入”变成“管理”,再变成“服务”
先说它解决了什么。接入层从“一台台导流”变成了“一次定义、全队生效”。开发者只需要关心车队的业务目标:精度要多少,允许的差分数据延迟是多少,哪些区域要用高精度,哪些区域可以接受降级,剩下的账号分配、挂载点选择、服务器切换都由平台层处理。
对自动驾驶公司而言,这等于把过去靠人工和电子表格完成的工作变成了编程对象。对移动机器人场景也一样,比如工厂里 20 台 AGV 同时跑,你不需要知道每台车背后连了哪个基站,只需要确认整个车队都订阅了同一套高可用定位服务即可。
这里也涉及很实际的成本收益。很多公司买了差分服务但账号利用率不高,用 fleet 聚合之后,可以按车队维度统一分析用量,有的设备长期闲置就调整订阅,而不是放任不管。
从我的经验来看,这种转变的本质是把“定位接入”从一次性交付变成了持续管理。以前项目交付完,设备落地之后基本就是黑盒运行;现在有了车队级策略和监控,定位质量变成可持续观测和调整的对象。这一点对运营阶段的帮助比接入阶段更大。
2. 面向开发者的能力拆解:新的车队定位 API 到底解决了哪些痛点
2.1 批量设备注册与统一凭据
要支持车队级,API 第一步一定是让设备可以被“批量管理”。一个合格的接口设计,至少应该包含几个基本操作:创建车队、批量添加设备、按设备查询定位状态、动态更新车队策略。设备本身可以先用 ID 注册,也可以由设备首次开机时自动上报、自动入队。
统一凭据是非常关键的细节。如果每台设备仍然要单独拿一个 NTRIP 账号,那对开发者来说并没有真正解脱。新解法是让整个 fleet 持有同一个 token,设备端 SDK 拿着 token 去请求服务,云端再按设备身份做授权和配额控制。这种做法很像云平台的 API Key 加 IAM 角色:管理面只需要管一个角色,控制面再去细分权限。
我在测试环境里习惯这样做,先建立一个车队:
curl -X POST "https://api.pointonenav.example/v1/fleets" \ -H "Authorization: Bearer <YOUR_API_KEY>" \ -H "Content-Type: application/json" \ -d '{ "name": "east-china-delivery", "service_region": "cn-east", "mode": "rtk", "fallback": "ppp-rtk", "max_correction_age": 5 }'正常响应会返回fleet_id。然后批量把设备挂进去:
curl -X POST "https://api.pointonenav.example/v1/fleets/east-china-delivery/devices:batchAdd" \ -H "Authorization: Bearer <YOUR_API_KEY>" \ -H "Content-Type: application/json" \ -d '{ "device_ids": ["AGV-001", "AGV-002", "AGV-003", "AGV-004", "AGV-005"] }'设备入队之后,每台设备会拿到 fleet 级别的 token,配合自身 device_id 去请求 correction data。后续新设备入队只需要两步:设备端写入 device_id,管理端把 device_id 加入 fleet 的 device list。整个流程已经不需要再碰那套“每台设备单独建 subscriber”的老逻辑。
2.2 更灵活的差分服务策略与覆盖选择
第二个关键点是策略。表面上看起来只是“精度策略”,背后其实是一整套地理和动态决策逻辑。RTK 依赖基准站网络,在城市里的固定率通常不错,但在城郊或者高速公路上,基准站覆盖可能变差。如果没有回退策略,设备可能长时间停在浮点解状态,位置精度根本不够用。
所以新的 API 应该让开发者能够指定 fallback 策略。我建议把策略设计成三个层次的组合:
- 首选模式:RTK 固定解。
- 次选模式:PPP-RTK 或 PPP,不依赖本地基站。
- 最低可用模式:SBAS 或普通单点定位。
这种组合让设备在跨区域运行时能够平滑切换,而不是出城的瞬间定位质量断崖式下降。很多开发者容易忽略这一点,以为配了 RTK 就万事大吉,结果一到郊区就翻车。
策略配置里另一个容易被忽略的参数是max_correction_age。差分改正数越新鲜,定位结果越准。如果允许的龄期太大,固定率数字看起来不错,但实际位置可能已经漂了几十厘米。按照 RTK 的实践经验,这个值建议控制在 5 到 10 秒以内,宽松一点的场景也别超过 30 秒。
2.3 观测和排障不再是“黑盒”
第三点是可观测性。老一代差分服务基本是“盲用”,你只能从接收机的状态灯或者 NMEA 输出里看到固定与否,出了问题很难定位。新特性把质量指标结构化之后,对开发者的价值非常大。至少应该能拿到这样一组指标:fix status、卫星数、差分龄期、基线长度、当前挂载点、切换事件、定位抖动。
有了这些指标,你可以做几件很实际的事情:给每台设备画一条定位质量的时间线;在设备长时间掉到 float 时触发告警;在挂载点切换后做自动回归,确认固定率没有受影响。这些不是锦上添花,而是大规模运营时的必备能力。
3. 一条实操路径:从建 fleet 到下发的完整过程
3.1 准备阶段:硬件和网络条件检查
写代码之前,先讲硬件。车端接收机至少要支持 RTCM 3.2 输入,最好带独立的 NTRIP client,或者能跑官方 SDK。不需要过度迷信接收机品牌,重点是确认天线的安装位置,避开多路径效应。车顶中间通常是最好的位置,不要在货箱边缘或者靠近金属围栏的地方装。
另一个经常被忽略的是网络链路。差分纠偏数据本身很小,几 KB/s 就够,但延迟和丢包率极其重要。4G 模块如果每隔几秒断一下,RTK 固定解会频繁丢失。我实测过的经验是:延迟 50ms 以内、丢包不超过 1% 时,固定率普遍稳定;超过这个门槛,再好的服务也救不回来。如果是 5G 模块,通常网络质量会好很多,但要注意流量套餐不要用共享限速的那种,否则高峰期差分数据被挤到后列,固定率照样崩。
3.2 用 API 创建车队并配置策略
到管理端建一个 fleet,配置策略。这个过程本身很简单,关键是策略参数要想清楚。拿前面那个 REST 调用为例,mode设成rtk,fallback设成ppp-rtk,意思是优先用 RTK 固定解,一旦 RTK 不可用就回退到 PPP-RTK,而不是直接掉到单点定位。这个组合是当前综合体验最稳的方案。
参数配置完之后,把设备批量挂进车队。这时候可以顺便检查返回结果里每台设备是否正常创建。有些平台会返回异步任务,你需要去查任务状态;有些会直接返回设备列表。无论哪种,都要确认没有部分失败的情况。
成功创建后,建议在管理端或者 API 里查看 fleet 的设备列表,确认每台设备显示为“已激活”状态。只有设备首次上报之后,状态才会从“已注册”变成正常,这一点不要着急。
3.3 设备端接入上报与质量监控
设备端的工作取决于你是使用现成 SDK 还是自己写 client。如果走官方 SDK,通常只要设置 server 地址、fleet token、device_id,SDK 会自动按设备当前坐标选择最近的服务节点,并负责重连和状态上报。这对多数团队是效率最高的方案。
如果是自己写 NTRIP client,最简流程是:设备开机后上报自己的粗略位置,服务端返回可用挂载点;然后建立 NTRIP 连接接收 RTCM 数据;接收机解算后,把 GGA 语句或状态帧回传,用于后台监控。逻辑本身不复杂,但很容易在细节上翻车,比如坐标系格式、NMEA 语句刷新频率、TCP keepalive 超时时间,这些都要单独调试。
我建议设备端至少每 30 秒回传一次质量指标,这样云端才能画出趋势图;如果遇到掉线,本地也要有日志留存,方便回看事件现场。别小看日志,没有日志的时候出了问题就只能靠猜。
3.4 一组合理的验收标准
接入完成后,不要看到“能定位”就收工。我一般会按下面几项做验收:
- 静态测试:车辆不动,连续运行 30 分钟,固定解占比应大于 95%。
- 动态测试:按正常路线跑一圈,记录定位抖动,理想情况下水平误差在 2 到 5 厘米。
- 切换测试:设备从城区开到郊区,确认能够从 RTK 平滑降级到 PPP,不出现长时间无解。
- 掉线恢复:人为断开网络 60 秒再恢复,观察重新固定时间,正常情况下应该在 30 秒内恢复。
这四项都过了,再考虑大规模上量。不要跳过切换测试和掉线恢复,这两项恰恰是运营阶段最容易出问题的环节。
4. 摸索中踩过的坑:车队级定位的实战排查
4.1 固定率不稳,先检查差分龄期而不是天线
很多团队一看到固定率下降,第一反应是天线坏了或者接收机有问题。其实在 RTK 系统里,天线被遮挡当然有影响,但如果是整个车队、大面积区域出现了固定率下滑,第一优先检查的一定是差分数据源。
要看的核心指标是age_of_corrections。假设设备已经 20 秒没有收到新的 correction,那它显示的 fixed 基本是悬的,随时可能跳回 float。这个值如果普遍超标,问题出在链路或者服务配置,跟天线没有关系。我见过太多次团队把天线拆下来重装,折腾半天,最后发现是 4G 模块的 APN 配错了。
4.2 一个覆盖策略不能适配所有城市
不同城市的地理环境差很多。高层峡谷、高架桥、树荫、隧道都会改变卫星可见性。就算同一个服务商,不同城市的基准站密度也不一样。把一套参数在所有车辆上硬套,在 A 城表现优秀,到 B 城可能频繁 float。
我的建议是按车队细分,至少按运营城市拆 fleet,给每个城市单独设置策略参数。不要因为省事把所有车合并成一个 fleet,后面排查问题的时候会非常痛苦。真正到调度层面,可以让设备自动上报当前城市编码,然后加载对应策略,但第一步先把 fleet 拆分好,不会出错。
4.3 批量接口的幂等与重试
批量接口有一个隐藏很深的坑:幂等性。批量添加设备时如果请求超时,你以为没有发出去,又重发一次,结果同一台设备被绑定两次,后面查状态时出现重复记录。正规的云服务 API 会提供 request_id 幂等键,调用时要带上,或者在客户端用设备清单做一次本地去重。
我们在实际项目中的做法是,每台设备的 device_id 作为唯一主键,服务端在批量 add 时遇到已存在设备就返回“已存在”而不是报错,这样重试不会产生副作用。如果你对接的 API 不支持这种语义,那只能在客户端自己保证,不然重复添加会污染数据。
4.4 常见问题速查表
| 症状 | 最可能原因 | 排查方向 |
|---|---|---|
| 固定率突然下降 | 差分龄期过大 | 查看最近基站切换,检查 4G 网络质量 |
| 特定区域一直 float | 该区域基准站覆盖稀疏 | 给该 fleet 配置 PPP 回退策略 |
| 批量添加部分失败 | 重复设备或 ID 格式不统一 | 规范化 device_id,使用幂等键 |
| 单台设备离线但不断连 | NTRIP 连接被网络层断开 | 检查 TCP keepalive 和超时设置 |
| 新设备接入状态异常 | fleet token 未正确下发 | 重新生成 token 并核对设备绑定关系 |
| 定位波动但固定率正常 | 天线多路径或安装位置不佳 | 调整天线位置,做静态测试验证 |
5. 开发者体验最近的变化,从提示工程到定位 API
5.1 为什么接口设计越来越像“明确的指令”
最近吴恩达在 DeepLearning.AI 的《ChatGPT Prompt Engineering for Developers》课程非常火,身边做云服务和硬件接入的同事也都在看。很多人觉得这和 GNSS 定位八竿子打不着,但我看完之后一个很深的感受是:原理完全相通——给系统的指令越明确,系统输出越稳定。
在提示工程里,你要描述角色、背景、输出格式,甚至给几个示例,模型才能给出符合预期的结果。定位 API 也是同样的道理:你得告诉服务端精度等级是多少,允许的改正数最大年龄是多少,降级策略是什么。你越准确地描述需求,服务端越能给出一致的结果;你含糊其辞,它就只能用默认参数,结果不可控。
5.2 给定位 API 的“提示词”清单
如果你正在集成新的车队级定位 API,可以把它当成一次“给系统写清晰指令”的练习:
- 不要只设
mode: rtk,把降级场景也写清楚。 - 不要用默认超时,按照自己的网络条件设置 correction_age 上限。
- 不要只记录 bool 型的 fixed 字段,记录具体的指标值,将来排查才有依据。
- 批量调用时把请求幂等化,这是任何 API 调用的基本素养。
这些经验和提示工程课程里“结构化输出”“边界条件”的建议几乎一一对应。对开发者来说,“如何给系统下指令”正在变成一种跨领域的通用能力,搞明白这个思路,对接任何复杂 API 都会顺手很多。
6. 最后再分享一点我的实操心得
如果你正在评估要不要用这套新特性,我的建议是先拿一个 5 台设备的小车队跑两周,不要一上来就上 50 台量产。重点观察三个东西:固定率能否稳定在 95% 以上、跨城市切换时的降级时长、批量接口在真实网络下的超时情况。
我个人在实际项目中踩得最深的坑,是只看平均固定率。车队平均 96% 听起来不错,但拆到单台设备,可能有一台长期只有 80%。车队级定位的价值就在于必须能下钻到单设备,否则和原来逐台看没有本质区别。建议让平台把每台设备的固定率单独暴露出来,运维上盯住 1% 的掉队者,比盯整个车队的平均值重要得多。
最后一个小技巧:策略里一定要预留“关闭降级”的开关。有些自动驾驶测试要求所有输出必须达到厘米级,不能接受降级坐标混在数据里;但日常运营又需要降级来保证可用性。两种模式不应该靠改代码实现,而应该是车队 API 里的一个标准字段。把这些想清楚了,你才能把定位从“能用”做到“好用”。