展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > c++如何解析GPGGA格式的NMEA原始卫星定位数据【进阶】

c++如何解析GPGGA格式的NMEA原始卫星定位数据【进阶】

GPGGA解析需手动按逗号切分并保留空字段,避免std::stringstream跳过空值导致字段错位。经纬度采用度分格式,需转换为十进制度数并处理方向。校验和应对$后至*前字符异或,结果转大写比对。UTC时间转换需使用timegm或_mkgmtime避免时区干扰,且日期需从其他帧获取。

本文目录

    解析NMEA的GPGGA数据,看起来不就是读字符串、拆字段吗?但实际踩过坑的人都知道,这里面细节相当多。一个不留神,经纬度、校验和、时间戳就全歪了。今天就把几个最核心、最容易出错的点掰开揉碎了说清楚,希望能帮大家少走弯路。

    c++如何解析GPGGA格式的NMEA原始卫星定位数据【进阶】

    为什么直接用 std::stringstream 拆分 GPGGA 字段会出错

    很多新手上来就用 std::stringstream >> 去读逗号分隔的字段,觉得省事。但GPGGA行里经常出现空字段——比如卫星还没锁定的时候,纬度、经度那一栏就是空的。这时候 >> 会直接跳过连续空白,把逗号之间的空字段吞掉,结果字段数量对不上,后面的解析全部错位。举个例子:$GPGGA,123519,,,,,,0,0,,,M,,M,,*6B 实际有14个字段(含校验前的 *),但用 >> 只能读出6–7个有效值。

    正确做法是按逗号手动切分,并且保留空字符串:

    std::vector split(const std::string& s, char delim) {
        std::vector tokens;
        std::string token;
        std::istringstream tokenStream(s);
        while (std::getline(tokenStream, token, delim)) {
            tokens.push_back(token); // 不 trim,保留空字段
        }
        return tokens;
    }
    • 第2、3、4、5、6、7、9、10等字段都可能为空,必须保留,否则解析 fix quality 或 satellites used 时会错位。
    • 注意NMEA行末尾可能带 \r\n,切分前先用 s.substr(0, s.find('*')) 截断校验部分,避免把 *6B 当成最后一个字段。
    • GPGGA固定为14个逗号分隔字段(不含起始 $),少于14说明数据损坏或非标准帧,直接丢弃。

    如何安全提取经纬度并转为十进制度数

    GPGGA的纬度(第3字段)和经度(第5字段)是度分格式——ddmm.mmmm 和 dddmm.mmmm,第4/6字段标明方向(N/S/E/W)。如果直接 stod(),会把 "4807.038" 当成4807度,显然不对。

    正确的转换逻辑:

    double parseCoord(const std::string& raw, const std::string& dir) {
        if (raw.empty()) return 0.0;
        double val = std::stod(raw);
        int deg = static_cast(val / 100);
        double min = val - deg * 100;
        double decimal = deg + min / 60.0;
        if (dir == "S" || dir == "W") decimal = -decimal;
        return decimal;
    }
    • 务必先检查第3/4/5/6字段是否非空,任一为空则坐标无效(fix quality == 0 时常见)。
    • 方向字段大小写敏感:"S" 和 "s" 不等价。NMEA规范全大写,但某些模块(如某些u-blox固件)可能输出小写,建议用 std::toupper 统一处理。
    • 浮点精度用 double 而非 float,否则在高纬度地区(如北纬60°)厘米级误差可达米级。

    校验和验证为何不能只比对最后两个字符

    很多人以为校验就是 *XX 里的 XX 直接跟计算结果比,但NMEA标准要求:校验和是 $ 到 * 之间所有字符的异或(不包括 $ 和 *),结果以两位十六进制大写ASCII表示。

    典型错误:把整行传给校验函数,或者漏掉 $ 后第一个字符。

    bool validateNMEAChecksum(const std::string& line) {
        size_t star_pos = line.find('*');
        if (star_pos == std::string::npos) return false;
        std::string data = line.substr(1, star_pos - 1); // $ 后到 * 前
        uint8_t checksum = 0;
        for (char c : data) checksum ^= c;
        std::string expected = fmt::format("{:02X}", checksum); // 需要 fmt 或自己 sprintf
        return line.substr(star_pos + 1, 2) == expected;
    }
    • 必须从 $ 后一位开始异或,不是从行首。
    • 校验和不区分大小写,但标准输出是大写;若接收端返回小写(如 *ab),需统一转大写再比。
    • 有些廉价模块(如某些ATGM336H兼容板)根本不发校验和(即无 *),此时应设白名单跳过校验,而非硬性拒绝整帧。

    time_t 与 UTC 时间戳转换容易忽略时区细节

    GPGGA第2字段是UTC时间(hhmmss.sss),但C++的 std::mktime 默认按本地时区解释 tm 结构,直接填完就转会出错。

    正确方式是构造UTC时间点后转为 std::time_t:

    std::time_t parseUTCtime(const std::string& timeStr, int year, int month, int day) {
        if (timeStr.length() < 6) return 0;
        struct std::tm t = {};
        t.tm_year = year - 1900;
        t.tm_mon = month - 1;
        t.tm_mday = day;
        t.tm_hour = std::stoi(timeStr.substr(0, 2));
        t.tm_min = std::stoi(timeStr.substr(2, 2));
        t.tm_sec = std::stoi(timeStr.substr(4, 2));
        t.tm_isdst = 0; // UTC 无夏令时
        return _mkgmtime(&t); // Windows:_mkgmtime;Linux/macOS:timegm
    }
    • timegm 不是C++标准函数,POSIX有,Windows需用 _mkgmtime,跨平台项目必须条件编译。
    • 第9字段是海拔高度单位(M),但第10字段是大地水准面差距单位(也标 M),二者数值意义不同,别混用。
    • 如果只关心相对时间差(如RTK差分延迟),其实不必转 time_t,直接解析 hhmmss.sss 为秒级 double 更轻量、无时区陷阱。

    最后说一个容易被忽略但非常关键的点:GPGGA本身不包含日期字段,日期来自GPRMC或GPZDA。如果只靠GPGGA,year/month/day 必须由上文帧或系统时钟补充,否则UTC时间戳毫无意义。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 C++
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。