mavros_gps_listener v0.1.0

ROS Noetic C++14 Exiv2 MAVROS 最后更新: 2026-03-18

GPS 数据采集 · 实时写入图片EXIF · 图像TCP客户端 —— 为无人机地理标签图像而生。

📖 概述

mavros_gps_listener 是一个 ROS 功能包,订阅来自 MAVROS 的 GPS 话题(包括处理后的 fix、原始 GPS 报文及速度向量),并将位置信息实时写入指定的 JPEG 图像文件。同时包含一个独立的 TCP 图像客户端,可从远端服务器接收图像并保存,便于与机载相机集成。

🎯 设计目标: 为无人机航测、地理标记摄影提供无缝的 GPS 元数据注入。每次收到 GPS 修复时,自动将经纬度、海拔写入 test.jpg (或自定义路径),方便后续分析。

核心模块

✨ 核心特性

🛰️ 多源GPS订阅

同时监听 global (NavSatFix), raw/fix (GPSRAW) 和 gps_vel (Vector3Stamped)。

🗺️ EXIF 地理标签

自动将纬度/经度/海拔写入 JPEG/TIFF 的 EXIF GPS 块,符合标准。

📡 原始数据解析

完整打印 fix_type, 卫星数, HDOP, VDOP, 速度, 偏航角, 精度因子等。

📸 图像TCP客户端

独立客户端类,接收二进制图像流并显示进度,轻松集成图传。

📋 元数据管理

支持读取、删除、检查GPS标签;支持度分秒有理数存储。

🧩 易于扩展

代码模块化,CMake 集成 Exiv2,可单独使用 gps_writer 库。

⚡ 快速体验

假设已经启动 MAVROS 并连接至飞控 ( /uav1/mavros/... ):

# 1. 运行监听节点 (自动将GPS写入 /home/xxx/gps_ws/test.jpg)
rosrun mavros_gps_listener gps_listener_node

# 2. 查看终端输出 (每秒刷新GPS状态)
# 3. 检查图片元数据
exiv2 -pa /home/xxx/gps_ws/test.jpg | grep GPS

或者使用独立的元数据工具(需要单独编译命令行工具,参考 CLI 部分)

📦 功能包结构

mavros_gps_listener/
├── package.xml
├── CMakeLists.txt
├── README.md
├── include/
│   ├── client.h
│   └── gps_metadata_writer.h
└── src/
    ├── gps_listener_node.cpp
    ├── client.cpp
    └── gps_metadata_writer.cpp

🖊️ GPSMetadataWriter — EXIF 元数据注入

基于 Exiv2 操作图像的 EXIF GPS 信息。符合 EXIF 标准 (GPSLatitude/Longitude 采用有理数数组表示度/分/秒)。

主要 API

bool writeGPSMetadata(const std::string& imagePath, double latitude, double longitude, double altitude = 0.0);

将十进制度坐标写入图片。海拔为正表示高于海平面。

bool writeDetailedGPSMetadata(const std::string& imagePath, const std::map<std::string, std::string>& gpsData);

直接写入 Exif 键值对(高级用法)。

std::map<std::string, std::string> readGPSMetadata(const std::string& imagePath);

读取所有 GPS 相关标签。

bool removeGPSMetadata(const std::string& imagePath);

删除所有 GPS 标签。

内部转换

decimalToDMS 将十进制如 39.9042 转换为 39°54'15.12" (度/分/秒*100);DMSToRational 生成有理数对 (度/1, 分/1, 秒/100);altitudeToRational 使用厘米单位。

👂 GPSListener Node — 核心节点

节点名称: mavros_gps_listener ;可执行文件: gps_listener_node

订阅话题 (带命名空间 /uav1)

话题类型回调处理
/uav1/mavros/global_position/globalsensor_msgs/NavSatFix更新 current_fix_,写入图片,打印信息
/uav1/mavros/global_position/raw/fixmavros_msgs/GPSRAW更新 current_raw_,写入图片,打印详情
/uav1/mavros/global_position/raw/gps_velgeometry_msgs/Vector3Stamped更新 current_vel_,显示速度

gpsFixCallbackgpsRawCallback 中均会调用 writer.writeGPSMetadata("/home/xxx/gps_ws/test.jpg", ...) ,因此每次收到 GPS 数据都会更新图片元数据。该路径可自行修改。

打印信息

终端每秒刷新一次,显示 Fix 状态、原始卫星信息、速度、精度因子等,包括 fix_type 含义 (2D/3D/RTK等)。

📸 ImageClient — TCP 图像接收

跨平台 socket 客户端 (Windows 需链接 ws2_32)。通信协议:先接收 uint64_t 表示图像数据大小(字节),然后接收二进制数据块,保存为文件。

使用方法

ImageClient client;
if (client.connectToServer()) {
    client.receiveImageData("received.jpg");
    client.disconnect();
}

该模块独立于 ROS,可在其他项目复用。

🔌 话题与消息详解

/uav1/mavros/global_position/global (NavSatFix)

/uav1/mavros/global_position/raw/fix (mavros_msgs/GPSRAW)

包含 PX4 原始 GPS 报文数据:

uint8 fix_type         // 0-8 (NO_GPS, 2D, 3D, RTK...)
uint8 satellites_visible
uint16 eph, epv         // 水平/垂直精度因子 (cm)
int32 lat, lon          // 纬度/经度 (1e-7 度)
int32 alt, alt_ellipsoid // 海拔/椭球高 (mm)
uint32 vel              // cm/s
uint16 cog              // 地面航向 (0.01度)
int16 yaw               // 偏航角 (0.01度)
uint32 h_acc, v_acc, vel_acc, hdg_acc // 精度 (mm, mm/s, millidegrees)
...

/uav1/mavros/global_position/raw/gps_vel (Vector3Stamped)

东北天速度 (m/s)。

🗺️ Exiv2 集成与 EXIF 标签映射

EXIF GPS 标签写入值
Exif.GPSInfo.GPSLatitudeRef"N" 或 "S"
Exif.GPSInfo.GPSLatitude有理数数组 [deg/1, min/1, sec*100/100]
Exif.GPSInfo.GPSLongitudeRef"E" 或 "W"
Exif.GPSInfo.GPSLongitude有理数数组
Exif.GPSInfo.GPSAltitudeRef0 (海平面以上) / 1 (以下)
Exif.GPSInfo.GPSAltitude有理数 (altitude_cm/100)
Exif.GPSInfo.GPSDateStampUTC 日期 "YYYY:MM:DD"
Exif.GPSInfo.GPSTimeStamp有理数数组 [hour/1, min/1, sec/1]
Exif.GPSInfo.GPSVersionID"2 2 0 0"

注:秒保留两位小数存储为 seconds*100/100

🔨 编译与依赖

依赖库

Ubuntu 20.04 (Noetic) 安装

sudo apt install ros-noetic-desktop-full
sudo apt install libexiv2-dev pkg-config
cd ~/catkin_ws/src
git clone https://github.com/your/mavros_gps_listener.git
cd ~/catkin_ws
catkin_make

CMake 中通过 pkg_check_modules(EXIV2 REQUIRED exiv2) 查找。

💡 独立命令行工具 (参考 README.md)

虽然当前节点未提供 CLI,但可通过编译额外工具调用 GPSMetadataWriter 实现独立操作:

# 写入GPS
./gps_writer -w test.jpg 39.9042 116.4074 50.5

# 读取GPS
./gps_writer -r test.jpg

# 删除GPS
./gps_writer -d test.jpg

# 检查GPS
./gps_writer -c test.jpg

(你需要自行创建 gps_writer_main.cpp 链接 gps_writer 库)

📋 完整代码示例:修改图片路径

gps_listener_node.cpp 中,找到 writer.writeGPSMetadata("/home/xxx/gps_ws/test.jpg", ...) ,替换为你希望的图片路径。也支持动态参数。

扩展:新增服务,每次触发保存当前GPS到指定图片。

🔍 故障排除

GPS 数据写入失败 (Exiv2 error) 确保图片路径可写,且图片格式为 JPEG/TIFF。安装 exiv2 并验证 exiv2 命令可用。
没有 GPS 数据输出 检查 MAVROS 是否发布话题:rostopic list | grep /uav1/mavros/global_position。确认飞控已解锁且收到卫星信号。
Socket 客户端连接失败 服务端是否启动?Windows下需要初始化 WSA,client.h 已处理。
编译时找不到 Exiv2 sudo apt install libexiv2-dev;或手动指定 -DEXIV2_INCLUDE_DIRS

📝 更新日志

版本 0.1.0 (2026-03-18)

⚖️ 许可证

BSD 3-Clause License

Copyright (c) 2026 Your Name

允许自由使用、修改、再发布,需保留版权声明及免责条款。详情见 package.xml 和 LICENSE 文件。

© 2026 mavros_gps_listener 贡献者 · 文档遵循 MIT 风格 · 生成于 2026-03-18