《机器人实践开发⑨:Foxglove可视化机器人的MyBag 数据回放》

数据回放是机器人调试中最核心的步骤。本篇介绍 Foxglove MyBag 的录制、回放、筛选、同步与导出流程,并分享适合实际工程的使用技巧,帮助你轻松重现机器人运行状态。


《机器人实践开发》系列文章,请读者前往阅读 👀

《机器人实践开发①:Foxglove 开发环境完整搭建指南(含常见坑位)》

《机器人实践开发②:Foxglove 嵌入式移植 + CMake 集成》

《机器人实践开发③:Foxglove可视化机器人的眼睛-视频》

《机器人实践开发④:Foxglove可视化机器人的耳朵-声音》

《机器人实践开发⑤:Foxglove可视化机器人的3D显示》

《机器人实践开发⑥:Foxglove可视化机器人传感器数据》

《机器人实践开发⑦:Foxglove可视化机器人的日志显示》

《机器人实践开发⑧:Foxglove可视化机器人的地图显示》

《机器人实践开发⑨:Foxglove可视化机器人的MyBag 数据回放》


Mcap 的核心类McapWriter


/// @brief An MCAP writer, used to log messages to an MCAP file.
class McapWriter final {
public:
  /// @brief Create a new MCAP writer.
  ///
  /// @note Calls to create from multiple threads are safe,
  /// unless the same file path is given. Writing to an MCAP
  /// writer happens through channel logging, which is thread-safe.
  ///
  /// @param options The options for the MCAP writer.
  /// @return A new MCAP writer.
  static FoxgloveResult<McapWriter> create(const McapWriterOptions& options);

  /// @brief Stops logging events and flushes buffered data.
  FoxgloveError close();

  /// @brief Default move constructor.
  McapWriter(McapWriter&&) = default;
  /// @brief Default move assignment.
  McapWriter& operator=(McapWriter&&) = default;
  ~McapWriter() = default;

  McapWriter(const McapWriter&) = delete;
  McapWriter& operator=(const McapWriter&) = delete;

private:
  explicit McapWriter(foxglove_mcap_writer* writer);

  std::unique_ptr<foxglove_mcap_writer, foxglove_error (*)(foxglove_mcap_writer*)> impl_;
};

MyBag录制开始

设置 录制的路径visualization_mcap_path
开始录制foxglove::McapWriter::create(mcap_options)

int FoxgloveVisualizationService::startFoxgloveVisualizationMcapService() {
LOG(INFO) << "startFoxgloveVisualizationMcapService" ;
if (visualization_mcap_enable) {
   foxglove::setLogLevel(foxglove::LogLevel::Info);
   foxglove::McapWriterOptions mcap_options = {};
   // 获取当前时间
   auto now = std::chrono::system_clock::now();
   std::time_t now_c = std::chrono::system_clock::to_time_t(now);
   std::tm local_tm;
   localtime_r(&now_c, &local_tm); // POSIX线程安全

   char visualization_mcap_path[128]; // 存储完整路径
   // 组装完整目录路径,例如 /config/mcap/2025-09-19_15-30-25
   snprintf(visualization_mcap_path, sizeof(visualization_mcap_path),
            "%s%04d-%02d-%02d_%02d-%02d-%02d.mcap",
            visualization_mcap_dir,
            local_tm.tm_year + 1900,
            local_tm.tm_mon + 1,
            local_tm.tm_mday,
            local_tm.tm_hour,
            local_tm.tm_min,
            local_tm.tm_sec);

   // 创建目录
   mkdir(visualization_mcap_dir, 0755);
   LOG(INFO) << "visualization_mcap_path: " << visualization_mcap_path;
   mcap_options.path = visualization_mcap_path;
   // mcap_options.truncate = true;
   auto writer_result = foxglove::McapWriter::create(mcap_options);
   if (!writer_result.has_value()) {
       std::cerr << "Failed to create writer: " << foxglove::strerror(writer_result.error()) << '\n';
       return 1;
   }
   visualization_mcap_writer = std::make_unique<foxglove::FoxgloveResult<foxglove::McapWriter>>(std::move(writer_result.value()));
}
}

结束录制

int FoxgloveVisualizationService::stopFoxgloveVisualizationMcapService() {
    LOG(INFO) << "stopFoxgloveVisualizationService" ;
    if (visualization_mcap_writer) {
        LOG(INFO) << "visualization_mcap_writer close";
        foxglove::FoxgloveError err = visualization_mcap_writer->value().close();
        if (err != foxglove::FoxgloveError::Ok) {
            LOG(INFO) << "Failed to close writer: " << foxglove::strerror(err);
        }
    }

}

foxglove 客户端导入录制数据

在这里插入图片描述

开始回放数据

在这里插入图片描述

回放数据时间筛选

在这里插入图片描述


友情提示🔔

🙏 感谢你的阅读!
如果这篇文章对你有所启发,欢迎关注我 ⭐,欢迎点击 “打赏支持作者” 支持一下我,你的支持是我持续创作的最大动力!
我会持续分享更多关于 智能摄像头 📷、机器人项目、 🤖音视频 RTC 🎧、App 开发 📱、嵌入式开发 🔧 等方向的实战经验,让你更快落地、更少踩坑。
欢迎浏览我其他文章 📚,或许能解决你当前的难题。
如果你正好在做相关项目产品,也欢迎随时私信我,一起技术交流、一起搞事情! 🤝💬📞 联系微信/电话:13826173658

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈视界师

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值