mavros_gps_listener v0.1.0
GPS 数据采集 · 实时写入图片EXIF · 图像TCP客户端 —— 为无人机地理标签图像而生。
📖 概述
mavros_gps_listener 是一个 ROS 功能包,订阅来自 MAVROS 的 GPS 话题(包括处理后的 fix、原始 GPS 报文及速度向量),并将位置信息实时写入指定的 JPEG 图像文件。同时包含一个独立的 TCP 图像客户端,可从远端服务器接收图像并保存,便于与机载相机集成。
test.jpg (或自定义路径),方便后续分析。
核心模块
- GPSMetadataWriter —— 基于 Exiv2 的 EXIF GPS 写入/读取/删除,支持十进制转度分秒,海拔有理数编码。
- GPSListener Node —— ROS 节点,订阅
/uav1/mavros/global_position/...话题,回调中调用 Writer 写入图片。 - ImageClient —— 跨平台 TCP 客户端 (Windows/Linux),接收服务端发来的图像数据并保存为文件。
✨ 核心特性
🛰️ 多源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
将十进制度坐标写入图片。海拔为正表示高于海平面。
直接写入 Exif 键值对(高级用法)。
读取所有 GPS 相关标签。
删除所有 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/global | sensor_msgs/NavSatFix | 更新 current_fix_,写入图片,打印信息 |
| /uav1/mavros/global_position/raw/fix | mavros_msgs/GPSRAW | 更新 current_raw_,写入图片,打印详情 |
| /uav1/mavros/global_position/raw/gps_vel | geometry_msgs/Vector3Stamped | 更新 current_vel_,显示速度 |
在 gpsFixCallback 和 gpsRawCallback 中均会调用 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)
- 纬度、经度 (度), 海拔(米), 状态(是否 fix)
/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.GPSAltitudeRef | 0 (海平面以上) / 1 (以下) |
| Exif.GPSInfo.GPSAltitude | 有理数 (altitude_cm/100) |
| Exif.GPSInfo.GPSDateStamp | UTC 日期 "YYYY:MM:DD" |
| Exif.GPSInfo.GPSTimeStamp | 有理数数组 [hour/1, min/1, sec/1] |
| Exif.GPSInfo.GPSVersionID | "2 2 0 0" |
注:秒保留两位小数存储为 seconds*100/100 。
🔨 编译与依赖
依赖库
- ROS (roscpp, sensor_msgs, geometry_msgs, mavros_msgs)
- Exiv2 (>= 0.27)
- PkgConfig
- Socket (系统自带)
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到指定图片。
🔍 故障排除
exiv2 命令可用。rostopic list | grep /uav1/mavros/global_position。确认飞控已解锁且收到卫星信号。sudo apt install libexiv2-dev;或手动指定 -DEXIV2_INCLUDE_DIRS。📝 更新日志
版本 0.1.0 (2026-03-18)
- ✨ 初始发布,基础 GPS 订阅与元数据写入
- 📡 支持 NavSatFix, GPSRAW, gps_vel
- 🖊️ 利用 Exiv2 实现 EXIF GPS 注入
- 📸 增加 TCP 图像客户端 ImageClient
- 📋 提供 CMake 构建,分离 gps_writer 库
⚖️ 许可证
BSD 3-Clause License
Copyright (c) 2026 Your Name
允许自由使用、修改、再发布,需保留版权声明及免责条款。详情见 package.xml 和 LICENSE 文件。
© 2026 mavros_gps_listener 贡献者 · 文档遵循 MIT 风格 · 生成于 2026-03-18