数据回放是机器人调试中最核心的步骤。本篇介绍 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

454

被折叠的 条评论
为什么被折叠?



