ROS笔记之rosbag的快速切片(C++实现)

news2025/1/6 17:04:52

ROS笔记之rosbag的快速切片(C++实现)

—— 杭州 2023-12-21 夜


code review

文章目录

  • ROS笔记之rosbag的快速切片(C++实现)
    • 1.运行效果
    • 2.文件结构
    • 3.fast_rosbag_slice.cpp
    • 4.CMakeLists.txt
    • 5.package.xml
    • 6.对fast_rosbag_slice.cpp进行函数封装

正常该功能是ROS官方命令行:rosbag filter来实现,但速度太慢.

代码抄自大佬的Github:https://github.com/berndpfrommer/fast_rosbag_slice.git


图片名称

1.运行效果

  • input_bag的情况
    在这里插入图片描述

  • 运行,想得到后50s的bag

rosrun fast_rosbag_slice fast_rosbag_slice -i a.bag -o output.bag -s 1686903228.56 -e 1686903278.56

在这里插入图片描述

耗时8.68s(windows虚拟机环境)

  • output_bag的情况
    在这里插入图片描述

2.文件结构

在这里插入图片描述

3.fast_rosbag_slice.cpp

// -*-c++-*--------------------------------------------------------------------
// Copyright 2022 Bernd Pfrommer <bernd.pfrommer@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <unistd.h>

#include <chrono>
#include <iostream>
#include <limits>

void usage()
{
  std::cout << "usage:" << std::endl;
  std::cout << "fast_rosbag_slice -i input_bag -o output_bag -s start_time -e stop_time "
            << std::endl;
}

static size_t process_bag(
  const std::string & inBagName, const std::string & outBagName, const double startTime,
  const double endTime)
{
  std::cout << "reading from bag: " << inBagName << std::endl;
  std::cout << "writing to bag: " << outBagName << std::endl;
  rosbag::Bag inBag;
  inBag.open(inBagName, rosbag::bagmode::Read);
  rosbag::Bag outBag;
  outBag.open(outBagName, rosbag::bagmode::Write);

  rosbag::View view(inBag);
  size_t numMessages(0);
  for (const rosbag::MessageInstance & m : view) {
    if (m.getTime().toSec() > endTime) {
      break;
    }
    if (m.getTime().toSec() >= startTime) {
      outBag.write(m.getTopic(), m.getTime(), m);
      numMessages++;
    }
  }
  inBag.close();
  outBag.close();
  return (numMessages);
}

int main(int argc, char ** argv)
{
  int opt;
  ros::Time::init();
  std::string inBag;
  std::string outBag;
  double startTime(0);
  double endTime(std::numeric_limits<double>::max());
  while ((opt = getopt(argc, argv, "i:o:s:e:h")) != -1) {
    switch (opt) {
      case 'i':
        inBag = optarg;
        break;
      case 'o':
        outBag = optarg;
        break;
      case 's':
        startTime = atof(optarg);
        break;
      case 'e':
        endTime = atof(optarg);
        break;
      case 'h':
        usage();
        return (-1);
      default:
        std::cout << "unknown option: " << opt << std::endl;
        usage();
        return (-1);
        break;
    }
  }
  if (inBag.empty() || outBag.empty()) {
    std::cout << "missing input or output bag name!" << std::endl;
    usage();
    return (-1);
  }
  const auto start = std::chrono::high_resolution_clock::now();

  size_t numMsg = process_bag(inBag, outBag, startTime, endTime);

  const auto end = std::chrono::high_resolution_clock::now();
  auto total_duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
  std::cout << "total time: " << total_duration * 1e-6 << " s" << std::endl;
  std::cout << "message processing rate: " << numMsg * 1e6 / total_duration << " hz" << std::endl;

  return (0);
}

4.CMakeLists.txt

#
# Copyright 2022 Bernd Pfrommer <bernd.pfrommer@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.5)
project(fast_rosbag_slice)


set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -Wpedantic -Werror")
set (CMAKE_CXX_STANDARD 14)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rosbag
  )


catkin_package()

include_directories(
  ${catkin_INCLUDE_DIRS}
)

# --------- sync test
add_executable(fast_rosbag_slice src/fast_rosbag_slice.cpp)
target_link_libraries(fast_rosbag_slice ${catkin_LIBRARIES})
#
# volumetric tracking node and nodelet
#
install(TARGETS fast_rosbag_slice
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
)

5.package.xml

<?xml version="1.0"?>
<package format="3">
  <name>fast_rosbag_slice</name>
  <version>1.0.0</version>
  <description>fast rosbag time slicer</description>
  <maintainer email="bernd.pfrommer@gmail.com">Bernd Pfrommer</maintainer>
  <license>Apache2</license>

  <buildtool_depend condition="$ROS_VERSION == 1">catkin</buildtool_depend>
  <depend condition="$ROS_VERSION == 1">roscpp</depend>
  <depend condition="$ROS_VERSION == 1">rosbag</depend>

  <export>
    <build_type condition="$ROS_VERSION == 1">catkin</build_type>
  </export>

</package>

6.对fast_rosbag_slice.cpp进行函数封装

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <chrono>
#include <iostream>
#include <limits>
#include <rosbag/bag.h>
#include <rosbag/view.h>

static size_t process_bag(
    const std::string &inBagName, const std::string &outBagName, const double startTime,
    const double endTime) {
    std::cout << "reading from bag: " << inBagName << std::endl;
    std::cout << "writing to bag: " << outBagName << std::endl;
    rosbag::Bag inBag;
    inBag.open(inBagName, rosbag::bagmode::Read);
    rosbag::Bag outBag;
    outBag.open(outBagName, rosbag::bagmode::Write);

    rosbag::View view(inBag);
    size_t numMessages(0);
    for (const rosbag::MessageInstance &m : view) {
        if (m.getTime().toSec() > endTime) {
            break;
        }
        if (m.getTime().toSec() >= startTime) {
            outBag.write(m.getTopic(), m.getTime(), m);
            numMessages++;
        }
    }
    inBag.close();
    outBag.close();
    return (numMessages);
}

int main() {
    std::string inBag = "/home/user/bag/a.bag";
    std::string outBag = "/home/user/bag/output.bag";
    double startTime = 1686903228.56;
    double endTime = 1686903278.56;

    const auto start = std::chrono::high_resolution_clock::now();

    size_t numMsg = process_bag(inBag, outBag, startTime, endTime);

    const auto end = std::chrono::high_resolution_clock::now();
    auto total_duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
    std::cout << "total time: " << total_duration * 1e-6 << " s" << std::endl;
    std::cout << "message processing rate: " << numMsg * 1e6 / total_duration << " hz" << std::endl;

    return (0);
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1327592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pycharm下执行conda命令提示无法识别解决方案

1 问题描述 win10环境命令行执行conda命令&#xff0c;报命令无法识别&#xff0c;错误信息如下&#xff1a; PS D:\code\cv> conda activate pt conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&a…

伽马校正:FPGA

参考资料&#xff1a; Tone Mapping 与 Gamma Correction - 知乎 (zhihu.com) Book_VIP: 《基于MATLAB与FPGA的图像处理教程》此书是业内第一本基于MATLAB与FPGA的图像处理教程&#xff0c;第一本真正结合理论及算法加速方案&#xff0c;在Matlab验证&#xff0c;以及在FPGA上…

106 uni-app 小程序之巨坑 not found path,not found methods v-for渲染出现报错

1.Component is not found in path 你是否像我一样&#xff0c;检查了无数遍&#xff0c;引入路径检查千万遍&#xff0c;就是没写错&#xff0c;小程序后台就是给你报错&#xff0c; 不用慌&#xff0c;心里默念&#xff1a;我不能砸电脑&#xff0c;我不能砸电脑&#xff0…

python可以做小程序研发嘛,python能做微信小程序吗

大家好&#xff0c;给大家分享一下python可以做微信小程序开发吗&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 大家好&#xff0c;给大家分享一下用python编写一个小程序&#xff0c;很多人还不知道这一点。下面详细解释一下用python代码…

[Spring 原理] 依赖查找

在Spring框架中&#xff0c;依赖注入是一项非常重要的功能&#xff0c;它能够帮助我们解决对象之间的依赖关系。而其中的doResolveDependency方法是Spring框架中执行依赖注入的核心方法之一。本篇博客将对doResolveDependency方法进行详细介绍&#xff0c;帮助读者更好地理解和…

手写题 - 实现一个带并发限制的异步调度器

题目 实现一个带并发限制的异步调度器 Scheduler&#xff0c;保证同时运行的任务最多有N个。 完善下面代码中的 Scheduler 类&#xff0c;使得以下程序能正确输出&#xff1a;class Scheduler {add(promiseCreator) { ... }// ... }const timeout (time) > new Promise(re…

Python 爬虫之下载视频(二)

爬取某Y的视频链接和标题 文章目录 爬取某Y的视频链接和标题前言一、基本思路二、程序解析阶段三、程序处理阶段总结 前言 这篇内容就简单给大家写个如何从网页上爬取某B主 主页 页面上所有的视频链接和视频标题。 这篇是基础好好看&#xff0c;下篇会根据这篇的结果做一个批…

八:爬虫-MySQL基础

一&#xff1a;MySQL数据库基础 1.MySQL数据库介绍 MySQL是一个[关系型数据库管理系统]&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Rela…

3D模型人物换装系统(二 优化材质球合批降低DrawCall)

3D模型人物换装系统 介绍原理合批材质对比没有合批材质核心代码完整代码修改总结 介绍 本文使用2018.4.4和2020.3.26进行的测试 本文没有考虑法线贴图合并的问题&#xff0c;因为生成法线贴图有点问题&#xff0c;放在下一篇文章解决在进行优化 如果这里不太明白换装的流程可以…

gem5 garnet l1 l2 cache的创建与相连

gem5 garnet l1 l2 cache的创建与相连 主要就是这个图&#xff1a; 细节 我们用的是gem5/configs/deprecated/example/fs.py #fs.py 引入了上两层路径&#xff0c;也就是当前可以看到 gem5/configs/路径。 addToPath("../../")#fs.py引入了gem5/configs/ruby/Ru…

PIC单片机项目(8)——基于PIC16F877A的温度光照检测装置的protues仿真

1.功能设计 使用PIC16F877A单片机&#xff0c;进行温度检测、光照检测。温度使用的是DS18B20&#xff0c;光照检测直接利用的AD转换。 光照太暗就开灯&#xff0c;温度太高就开风扇。温度阈值和光照阈值都实时显示在LCD1602屏幕上面。 完成了protues仿真。文件里面包含代码和仿…

图片转excel:“保留数字格式”在什么场景下该勾

保留数字格式是什么意思呢&#xff1f;顾名思义&#xff0c;就是将转出来的数字保留为数字格式&#xff0c;而不是文本格式。我们知道&#xff0c;OCR程序将图片上的文字识别为电脑可编辑的文字后&#xff0c;如果导入到excel不加处理&#xff0c;则单个数字过长的文字就会被ex…

Python整数常用的方法汇总与Python3 File(文件) 方法

Python整数常用的方法汇总 python&#xff13;基础之整数常用的方法整理 希望对大家学习或者使用python3能具有一定的参考价值。 __abs__ #返回一个数的绝对值 __add__ #两数相加 __and__ #两数按位与操作 __bool__ …

04-JVM字节码文件结构深度剖析

一、源代码 package com.tuling.jvm;public class TulingByteCode {private String userName;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName userName;} }二、通过javap -verbose TulingByteCode .class反编译 //…

RobotFramework 自动化测试实战进阶篇

工具 Robotframework, 采用PO设计模式 PO模型 PO模型即Page Objects&#xff0c;直译意思就是“页面对象”&#xff0c;通俗的讲就是把一个页面&#xff0c;或者说把一个页面的某个区域当做一个对象&#xff0c;通过封装这个对象可以实现调用。 PO设计的好处 代码复用&…

python实现简单选择排序法

对于排序的方法中&#xff0c;简单选择排序法是相对符合人类的思维的一种方式&#xff0c;对于简单选择排序方法的核心思想是&#xff1a; 从待排序的序列集合中&#xff0c;找到最大值或者是最小值&#xff0c;然后将该值放置在其在最终的排序序列中的位置&#xff0c;也就是…

4.2 克隆

一&#xff0c;什么是克隆&#xff1f; 克隆是指通过共享缓冲区来复制内容&#xff08;例如&#xff0c;两个窗口共享相同的内容&#xff09;。 克隆可用于提高性能&#xff1a; 可以减少所需的更新次数。 你可以在多个显示器上显示内容&#xff0c;但只需要更新一个缓冲区…

信息论安全与概率论

目录 一. Markov不等式 二. 选择引理 三. Chebyshev不等式 四. Chernov上限 4.1 变量大于 4.2 变量小于 信息论安全中会用到很多概率论相关的上界&#xff0c;本文章将梳理几个论文中常用的定理&#xff0c;重点关注如何理解这些定理以及怎么用。 一. Markov不等式 假定…

大模型之二十一-小语言模型塞道开启

当前提到大语言模型&#xff0c;大家想到的都是动辄百亿规模以上参数量的模型&#xff0c;13B、70B都是稀疏平常入门级的&#xff0c;但是目前从模型层面来看&#xff0c;模型参数量的规模两极分化已经来临&#xff0c;早期各大公司为了效果怼上去&#xff0c;采取了简单粗暴的…

OpenSergo使用详解

简介 OpenSergo是一个基于微服务治理的标准和生态&#xff0c;覆盖了服务元信息、流量治理、服务容错、数据库/缓存治理、服务注册发现、配置治理等十几个关键领域&#xff0c;覆盖了完整的微服务生命周期&#xff08;从开发态到测试态&#xff0c;到发布态&#xff0c;再到运…