ROS C++ : 读取RosBag包

文章目录

    • 1. 读取单个话题
      • 1.1. 核心代码
      • 1.2. 完整示例
    • 2. 读取多个话题
      • 2.1. 核心代码
      • 2.2. 完整示例
    • 3. 读取全部话题
      • 3.1. 核心代码
      • 3.2. 读取方式1
      • 3.3. 读取方式2
      • 3.4. 完整示例

1. 读取单个话题

1.1. 核心代码

   // 获取名为"my_topic"的话题的迭代器
  rosbag::View view(bag, rosbag::TopicQuery("my_topic"));

1.2. 完整示例


#include <ros/ros.h>
#include <rosbag/bag.h>
#include <std_msgs/String.h>
 
int main(int argc, char** argv)
{
  // 初始化ROS节点
  ros::init(argc, argv, "play_bag_node");
  ros::NodeHandle nh;
 
  // 创建ROSbag对象,打开bag文件
  rosbag::Bag bag;
  bag.open("example.bag", rosbag::bagmode::Read);
 
  // 获取名为"my_topic"的话题的迭代器
  rosbag::View view(bag, rosbag::TopicQuery("my_topic"));
 
  // 循环遍历话题中的所有消息
  for (rosbag::View::iterator it = view.begin(); it != view.end(); ++it)
  {
    // 转换消息类型
    std_msgs::String::ConstPtr msg = it->instantiate<std_msgs::String>();
 
    if (msg != NULL)
    {
      // 打印消息内容
      ROS_INFO("Message: %s", msg->data.c_str());
    }
  }
 
  // 关闭bag文件
  bag.close();
 
  return 0;
}

2. 读取多个话题

2.1. 核心代码

 // 获取三个话题的迭代器
  rosbag::View view(bag, rosbag::TopicQuery("my_string_topic") && rosbag::TopicQuery("my_image_topic") && rosbag::TopicQuery("my_laser_topic"));

2.2. 完整示例


#include <ros/ros.h>
#include <rosbag/bag.h>
#include <std_msgs/String.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/LaserScan.h>
 
int main(int argc, char** argv)
{
  // 初始化ROS节点
  ros::init(argc, argv, "play_bag_node");
  ros::NodeHandle nh;
 
  // 创建ROSbag对象,打开bag文件
  rosbag::Bag bag;
  bag.open("example.bag", rosbag::bagmode::Read);
 
  // 获取三个话题的迭代器
  rosbag::View view(bag, rosbag::TopicQuery("my_string_topic") && rosbag::TopicQuery("my_image_topic") && rosbag::TopicQuery("my_laser_topic"));
 
  // 循环遍历话题中的所有消息
  for (rosbag::View::iterator it = view.begin(); it != view.end(); ++it)
   {
        // 从bag文件中读取消息
        const rosbag::MessageInstance& msg = *it;
        
        // 根据消息类型进行强制转换
        if (msg.isType<std_msgs::String>()) 
        {
            std_msgs::String::ConstPtr str_msg = msg.instantiate<std_msgs::String>();
            ROS_INFO_STREAM("String message: " << str_msg->data);
        }
        else if (msg.isType<sensor_msgs::Image>()) 
        {
            sensor_msgs::Image::ConstPtr img_msg = msg.instantiate<sensor_msgs::Image>();
            ROS_INFO_STREAM("Image message: " << img_msg->header.stamp);
            // 在此处添加处理Image消息的代码
        }
        else if (msg.isType<sensor_msgs::LaserScan>())
         {
            sensor_msgs::LaserScan::ConstPtr scan_msg = msg.instantiate<sensor_msgs::LaserScan>();
            ROS_INFO_STREAM("LaserScan message: " << scan_msg->header.stamp);
            // 在此处添加处理LaserScan消息的代码
        }
 
   }
 
    // 关闭bag文件
    bag.close();
    
    return 0;
    
}
 

3. 读取全部话题

3.1. 核心代码


rosbag::View view(bag);

或者

 rosbag::View view(bag, rosbag::TopicQuery(bag.getTopics()));

3.2. 读取方式1

    rosbag::Bag bag;
    bag.open(bagpath, rosbag::BagMode::Read);
    if(!bag.isOpen())
    {
        cout<<"can't open bag file!"<<endl;      
    }

    rosbag::View view(bag);
    rosbag::View::iterator it = view.begin();
    int iIndexTopic = 0;
    for(;it!= view.end(); it++)
    {
        if(it->getTopic() == "") continue;
        m[it->getTopic()] = 1;
 
       cout << "bag : " << it->getTopic() << it->getDataType() <<endl;
    }

3.3. 读取方式2

   int topic_num = view.getConnections().size();
   std::vector<std::string> tmp_topic;
    for (int i = 0; i < topic_num; i++)
    {
        tmp_topic.push_back(view.getConnections().at(i)->topic);
     }

3.4. 完整示例


#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <ros/ros.h>
#include <string>
#include <vector>
// 定义一个函数,用于回放多个话题的数据
// 参数:
// - bag_filename: ROSbag文件名
// - topics: 一个包含多个话题名的vector,如果为空,则回放所有话题的数据
void playbackRosbag(const std::string& bag_filename, const std::vector<std::string>& topics = {})
 {
  	// 创建ROS节点
    // ros::NodeHandle nh("~");
    ros::NodeHandle nh;//sukai
 
  // 创建ROS话题发布器
  std::vector<ros::Publisher> pubs;
  for (const auto& topic : topics.empty() ? bag.getTopics() : topics)
  {
    if (topic == "/image") 
    {
      pubs.push_back(nh.advertise<sensor_msgs::Image>(topic, 1));
    }
    else if (topic == "/scan") 
    {
      pubs.push_back(nh.advertise<sensor_msgs::LaserScan>(topic, 1));
    }
    else if (topic == "/string") 
    {
      pubs.push_back(nh.advertise<std_msgs::String>(topic, 1));
    }
    else 
    {
      ROS_WARN_STREAM("Unknown topic: " << topic);
    }
  }
 
  // 回放数据
  // rosbag::Bag bag(bag_filename, rosbag::bagmode::Read);
  rosbag::Bag bag;//sukai
  bag.open(bag_filename, rosbag::bagmode::Read); //sukai
  
  rosbag::View view(bag, rosbag::TopicQuery(topics.empty() ? bag.getTopics() : topics));
  
  for (const auto& msg : view)
  {
    ros::Time timestamp = msg.getTime();
    std::string topic = msg.getTopic();
    if (topic == "/image") 
    {
      sensor_msgs::Image::ConstPtr image = msg.instantiate<sensor_msgs::Image>();
      if (image != nullptr) 
      {
        pubs[0].publish(image);
      }
    }
    else if (topic == "/scan") 
    {
      sensor_msgs::LaserScan::ConstPtr scan = msg.instantiate<sensor_msgs::LaserScan>();
      if (scan != nullptr) 
      {
        pubs[1].publish(scan);
      }
    }
    else if (topic == "/string") 
    {
      std_msgs::String::ConstPtr str = msg.instantiate<std_msgs::String>();
      if (str != nullptr) 
      {
        pubs[2].publish(str);
      }
    }
    else 
    {
      ROS_WARN_STREAM("Unknown topic: " << topic);
    }
  }
 
  // 关闭ROSbag文件
  bag.close();
 
  ROS_INFO_STREAM("Playback finished!");
}

主函数使用


int main(int argc, char** argv)
{
	ros::init(argc, argv, "rosbag_recorder_player");
  
	// 回放ROSbag文件中的所有话题数据
	playbackRosbag(bag_filename);
 
	// 回放ROSbag文件中的指定话题数据
	std::vectorstd::string playback_topics = {"/scan", "/string"};
	
	//playbackRosbag(bag_filename, playback_topics);
	playbackRosbag(bag_filename);

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java中的封装、继承、多态

目录 封装 概念 包 继承 多态 向上转型 一、直接赋值 二、方法传参 三、返回值 向上转型注意事项 向下转型 格式 重写 重写和重载的区别 动态绑定 静态绑定和动态绑定 封装 概念 简单来说就是套壳屏蔽细节。 举例&#xff1a; 想要访问它们时需要一些“接口”…

Java项目实战II基于Java+Spring Boot+MySQL的大创管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 在当前创新创业氛围浓厚的背景下&#xff0c;大学生创新创业项目&#xff08;简称“大创”&#xff0…

国内旅游:现状与未来趋势分析

在当今社会快速发展的背景下&#xff0c;国内旅游更是呈现出蓬勃的发展态势。中国&#xff0c;这片拥有悠久历史、灿烂文化和壮丽山河的广袤土地&#xff0c;为国内旅游的兴起与发展提供了得天独厚的条件。 本报告将借助 DataEase 强大的数据可视化分析能力&#xff0c;深入剖…

基于SpringBoot的学习资源共享平台

运行环境: jdk8tomcat9mysqlIntelliJ IDEAmavennodejs 设计选用前后端分离的单体架构方式 后端&#xff1a;SpringBootMybatis-PluslogbackElasticsearchRedisMySQLJwtsmtp阿里云OSS 前端&#xff1a;WebPackVueJsAnt Designaxios 主要模块&#xff1a;反馈管理、资源管理、…

【最新】微信小程序连接onenet——stm32+esp8266+onenet实现查看温湿度,控制单片机

微信小程序——stm32esp8266onenet实现查看温湿度&#xff0c;控制单片机 &#xff08;最新已验证&#xff09;stm32 新版 onenet dht11esp8266/01s mqtt物联网上报温湿度和控制单片机(保姆级教程) &#xff1a;↓↓&#x1f447; &#x1f447; &#x1f447; &#x1f447…

unreal engine5制作动作类游戏时,我们使用刀剑等武器攻击怪物或敌方单位时,发现攻击特效、伤害等没有触发

UE5系列文章目录 文章目录 UE5系列文章目录前言一、问题分析二、解决方法1. 添加项目设置碰撞检测通道2.玩家角色碰撞设置3.怪物角色碰撞预设 最终效果 前言 在使用unreal engine5制作动作类游戏时&#xff0c;我们使用刀剑等武器攻击怪物或敌方单位时&#xff0c;发现攻击特效…

(17)MATLAB使用伽马(gamma)分布生成Nakagami-m分布的方法1

文章目录 前言一、使用伽马分布生成Nakagami分布随机变量的方法一二、MATLAB仿真代码后续 前言 MATLAB在R2013a版本中引入Nakagami分布对象&#xff0c;可以用来生成Nakagami随机变量。但是在更早的MATLAB版本中&#xff0c;并没有可以直接生成 Nakagami分布的随机变量的内置的…

51单片机系列-按键检测原理

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 独立按键是检测低电平的。 下面我们来看一张对应的电路原理图&#xff1a; 在这张图当中&#xff0c;P1&#xff0c;P2&#xff0c;P3内部都上拉了电阻&#xff0c;但是P0没有&am…

一款基于.NET开发的简易高效的文件转换器

前言 今天大姚给大家分享一款基于.NET开发的免费&#xff08;GPL-3.0 license&#xff09;、简易、高效的文件转换器&#xff0c;允许用户通过Windows资源管理器的上下文菜单来转换和压缩一个或多个文件&#xff1a;FileConverter。 使用技术栈 ffmpeg&#xff1a;作为文件转换…

知识图谱入门——10:使用 spaCy 进行命名实体识别(NER)的进阶应用:基于词袋的实体识别与知识抽取

在构建知识图谱的过程中&#xff0c;如何准确地识别和提取实体是关键。spaCy 提供了强大的命名实体识别&#xff08;NER&#xff09;功能&#xff0c;我们可以结合自定义规则和工具来实现更精准的实体抽取。本文将详细探讨如何在 spaCy 中实现自定义实体抽取&#xff0c;包括使…

【Nacos 架构 原理】服务发现模块之Nacos注册中心服务数据模型

文章目录 服务&#xff08;Service&#xff09;和服务实例&#xff08;Instance&#xff09;定义服务服务元数据定义实例实例元数据持久化属性 集群定义集群 生命周期服务的生命周期实例的生命周期集群的生命周期元数据的生命周期 服务&#xff08;Service&#xff09;和服务实…

[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入

信息收集 IP AddressOpening Ports10.10.11.28TCP:22&#xff0c;80 $ nmap -p- 10.10.11.28 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 e3:54:…

计算机视觉——图像修复综述篇

目录 1. Deterministic Image Inpainting 判别器图像修复 1.1. sigle-shot framework (1) Generators (2) training objects / Loss Functions 1.2. two-stage framework 2. Stochastic Image Inpainting 随机图像修复 2.1. VAE-based methods 2.2. GAN-based methods …

第 21 章 一条记录的多幅面孔——事务的隔离级别与 MVCC

21.1 事前准备 CREATE TABLE hero ( number INT, NAME VARCHAR ( 100 ), country VARCHAR ( 100 ), PRIMARY KEY ( number ) ) ENGINE INNODB CHARSET utf8;INSERT INTO hero VALUES ( 1, 刘备, 蜀 );21.2 事务隔离级别 在保证事务隔离性的前提下&#xff0c;使用不同的隔…

RTX4060+ubuntu22.04+cuda11.8.0+cuDNN8.6.0 如何根据显卡型号和系统配置cuda和cuDNN所需的安装环境

文章目录 &#x1f315;电脑原配置&#x1f315;安装cuda和cuDNN前的环境选择&#x1f319;cuDNN与CUDA tookit和nvidia driver的对应关系&#x1f319;cuda版本选择⭐查看自己的nvidia driver版本和最大支持的CUDA版本⭐最小支持版本 &#x1f319;查看11.8.0版本的cuda和ubun…

Redis:hash类型

Redis&#xff1a;hash类型 hash命令设置与读取HSETHGETHMGETHSETNX 哈希操作HEXISTSHDELHKEYSHVALSHGETALLHLENHINCRBYHINCRBYFLOAT 内部编码ziplisthashtable 目前主流的编程语言中&#xff0c;几乎都提供了哈希表相关的容器&#xff0c;Redis自然也会支持对应的内容&#xf…

数据结构之树(4)

摘要&#xff1a;本篇主要讲哈夫曼树、并查集、二叉排序树、平衡二叉树等&#xff0c;非常非常非常重要&#xff01;&#xff01;&#xff01; 一、哈夫曼树 基于霍夫曼树&#xff0c;利用霍夫曼编码进行通信可以大大提高信道利用率&#xff0c;缩短信息传输时间&#xff0c;…

OpenCV透视变换

#透视变换 import cv2 import numpy as np import matplotlib.pyplot as pltimg cv2.imread(coins.jpg,1)imgInfo img.shape height imgInfo[0] width imgInfo[1] #src 4->dst 4 (左上角 左下角 右上角 右下角) matSrc np.float32([[200,100],[200,400],[600,100],[wid…

Linux:进程间通信之信号量

system V的进程间通信除了共享内存&#xff0c;还有消息队列和信号量 IPC&#xff08;进程间通信的简称&#xff09; 消息队列 消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法 每个数据块都被认为是有一个类型&#xff0c;接收者进程接收的数据块可以有不同…

Ray_Tracing_The_Next_Week下

5image Texture Mapping 图像纹理映射 我们之前虽然在交点信息新增了uv属性&#xff0c;但其实并没有使用&#xff0c;而是通过p交点笛卡尔坐标确定瓷砖纹理或者大理石噪声纹理的值 现在通过uv坐标读取图片&#xff0c;通过std_image库stbi_load&#xff08;path&#xff09;…