讲师中心 微信公众号
AI工具推荐 视频效率加速

c++如何解析ROS1/ROS2的Bag包文件数据_rosbag库使用【深度】

小敏大大_3564

小敏大大_3564

发布时间:2026-04-12 23:41:06

|

1022人浏览过

|

来源于php中文网

原创

ROS1 C++ API读取.bag报“No such file or directory”错误,主因是未链接librosbag_storage依赖,CMakeLists需同时find_package rosbag和rosbag_storage并target_link_libraries二者;ROS2则须用rosbag2_cpp+rosbag2_storage,且storage_id必须设为"sqlite3"。

c++如何解析ros1/ros2的bag包文件数据_rosbag库使用【深度】

ROS1 bag 文件解析:用 rosbag C++ API 读取消息时为何报错 “No such file or directory”?

直接用 rosbag::Bag 打开 .bag 文件失败,大概率不是路径写错,而是没链接 librosbag 或漏了 rosbag_storage 依赖。ROS1 的 C++ API 实际是两层:上层 rosbag(提供 Bag 类)依赖下层 rosbag_storage(负责底层 I/O 和索引解析),CMakeLists.txt 中必须显式添加:

  • find_package(rosbag REQUIRED) 和 find_package(rosbag_storage REQUIRED)
  • target_link_libraries(your_node ${rosbag_LIBRARIES} ${rosbag_storage_LIBRARIES})
  • 头文件需同时包含 #include <rosbag></rosbag> 和 #include <rosbag></rosbag>(后者用于时间范围过滤)

典型错误是只 link rosbag,导致运行时报 undefined symbol: _ZN7rosbag3Bag4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj 这类符号缺失——本质是 rosbag_storage 的 so 没进链接列表。

ROS2 bag 解析不能用 rosbag 库,必须用 rosbag2_cpp + rosbag2_storage

ROS2 完全重构了 bag 格式(SQLite3 + 自定义序列化),rosbag(ROS1)库完全不兼容 ROS2 的 .db3 文件。正确做法是:

  • 依赖 rosbag2_cpp(提供 SequentialReader、StorageOptions 等核心类)和 rosbag2_storage(实现底层读取器插件)
  • 打开 bag 时必须指定存储 ID:storage_options.storage_id = "sqlite3";,否则默认用 mock 插件,读出来全是空数据
  • 消息类型需提前注册:调用 converter_options.output_serialization_format = "cdr"; 并确保 rmw_implementation 与 bag 写入时一致(常见坑:bag 是 cyclonedds 写的,你用 fastrtps 读会反序列化失败)

示例关键代码段:

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

立即学习“C++免费学习笔记(深入)”;

rosbag2_storage::StorageOptions storage_options;
storage_options.uri = "/path/to/ros2_bag";
storage_options.storage_id = "sqlite3";
rosbag2_cpp::ConverterOptions converter_options;
converter_options.output_serialization_format = "cdr";
reader.open(storage_options, converter_options);

跨 ROS 版本解析的关键障碍:消息定义不匹配

即使成功打开 bag,read_next() 返回的消息指针(std::shared_ptr<:serializedbagmessage></:serializedbagmessage>)仍可能解包失败,根本原因是 .msg 定义版本不一致。比如:

  • ROS1 bag 中的 sensor_msgs/PointCloud2 使用 uint8[] data 字段,而 ROS2 对应消息改用 uint8[] data + 显式 row_step 和 point_step,字段顺序和对齐方式不同
  • 自定义 msg 若在 ROS1 和 ROS2 中未严格保持字段名、类型、顺序一致,rosidl_runtime_cpp::get_message_type_support_handle 会返回 null,导致 deserialize 崩溃
  • 解决方法不是硬编码解析,而是用 ros2 run rosidl_runtime_cpp generate_interfaces 导出对应版本的 msg 头文件,并确保编译时链接的 rosidl_typesupport_* 与 bag 生成环境一致

性能陷阱:逐条 read_next() 在大 bag 上极慢,别忽略 read_until() 和缓存策略

对 10GB 级别的 bag,用循环 while (reader.has_next()) { reader.read_next(); } 可能比 Python 的 rosbag.Bag 还慢——因为每次调用都触发 SQLite 查询+反序列化+内存拷贝。提速要点:

  • 用 reader.get_all_topics_and_types() 预过滤只关心的 topic,避免加载无关消息
  • 对时间连续的数据(如 IMU),用 reader.seek(time_point) 跳转起始位置,再配合 read_next() 批量读取
  • 若需随机访问,别自己实现索引;ROS2 的 SequentialReader 不支持 seek,应改用 RandomAccessReader(ROS2 Humble+ 支持,但需手动构建,文档极少)
  • 最实际的优化:把消息内容 memcpy 到预分配的 buffer,避免频繁 new/delete,尤其对 sensor_msgs/Image 这类大 payload

真正卡住的往往不是格式解析,而是没意识到 bag 的 I/O 模式和内存模型和普通文件完全不同——它本质是个带 schema 的嵌入式数据库,按需索引比暴力扫描重要得多。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

3371

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1025

2023.12.29

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

12185

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

5527

2024.08.14

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

0

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn