首页 > 其他分享 >Rosbag数据解析实例

Rosbag数据解析实例

时间:2024-08-15 22:56:09浏览次数:7  
标签:obj msgs Rosbag bag 实例 time marker 解析 rosbag

Rosbag数据解析实例

文章目录


前言

今天写代码出了bug,解问题花了点时间。本来打算介绍一下基于bag数据,解析数据并通过rviz可视化的,现在是晚上8点,准备下班拉,只能回家或者明天上午早点写,希望大家原谅。
前几篇文章大家可以回看一下。

一、rosbag相关指令

rosbag常用命令

rosbag check  	    检查一个包是否可以在当前系统中播放,是否需要迁移
Bag file does not need any migrations.表示不需要迁移
rosbag compress  	压缩一个或多个bag文件
rosbag compress命令用于压缩ROS bag文件,‌它提供了两种压缩格式:‌BZ2和LZ4。‌BZ2压缩格式虽然占用的硬盘空间较小,‌但播放速度较慢;‌而LZ4压缩格式虽然对体积的压缩效果不明显,‌但播放速度有显著提高。
rosbag decompress  	解压缩一个或多个bag文件
解压缩一个或多个bag文件
每次解压缩文件之前,会备份每个包文件(扩展名为 .orig.bag),如果备份文件已存在(并且未指定 -f 选项),则该工具将不会解压缩该文件
rosbag filter  	    根据条件过滤bag文件内容
根据条件过滤bag文件内容,显示与指定python语法的逻辑表达式匹配的消息
rosbag filter input.bag output.bag "逻辑表达式"
rosbag filter input.bag output.bag "m.data=='foo'"
其中,input.bag表示过滤之前的bag文件,output.bag表示过滤之后的bag文件。
逻辑表达式中的 m 表示 msg,另外,还有 topic 表示 topic,t 表示 timestamp
例如
rosbag filter big.bag small.bag "topic == '/chatter'"
rosbag fix  	    修复bag文件中的消息,以便在当前系统中播放
如前rosbag check 所述,如果bag文件需要迁移,则可以使用 rosbag fix 修复。
rosbag fix old.bag repaired.bag myrules.bmr
其中,old.bag为修复之前的bag文件,repaired.bag 为修复之后的bag文件,myrules.bmr为修复规则,修复规则相关详见 包迁移机制 。
rosbag info  	    查看bag文件简要信息
例如:
桌面$ rosbag info 20240805114530.bag
path:        20240805114530.bag
version:     2.0
duration:    30.0s
start:       Aug 05 2024 11:45:10.69 (1722829510.69)
end:         Aug 05 2024 11:45:40.66 (1722829540.66)
size:        257.6 MB
messages:    8742
compression: none [280/280 chunks]
types:       autopilot_msgs/BinaryData      [fc52aedbbd8b2b2e49bf64cab07160d9]
             std_msgs/String                [992ce8a1687cec8c8bd883ec73ca41d1]
             visualization_msgs/Marker      [4048c9de2a16f4ae8e0538085ebf1b97]
             visualization_msgs/MarkerArray [d155b9ce5188fbaf89745847fd5882d7]
topics:      /chassis/vehicle_state             3000 msgs    : autopilot_msgs/BinaryData     
             /hadmap_engine/map_msg              300 msgs    : autopilot_msgs/BinaryData     
             /localization/global               2999 msgs    : autopilot_msgs/BinaryData     
             /perception/camera/trfclts_state    518 msgs    : std_msgs/String 
rosbag play  	    以时间同步的方式播放一个或多个bag文件的内容
以时间同步的方式播放一个或多个bag文件的内容,在播放时可以随时按 空格键 以暂停播放,同时暂停播放后,可以按 s 键以单步播放。
rosbag record  	    记录一个包含指定topic内容的bag文件
要记录指定话题的数据,可以使用以下命令:
rosbag record -O <bag_file_name> <topic_name>
其中,<bag_file_name> 是要保存的 bag 文件的名称,<topic_name> 是要记录的话题名称。例如,要记录名为 /sensor_data 的话题数据,并将其保存为 sensor_data.bag 文件,可以使用以下命令:
rosbag record -O sensor_data.bag /sensor_data
rosbag reindex      重新索引一个或多个bag文件
用于修复损坏的包文件(或 ROS 版本 0.11 之前记录的包文件)。如果由于任何原因未完全关闭包,则索引信息可能会损坏。使用该工具重新读取消息数据并重建索引。
在重新索引包之前,会备份每个包文件(扩展名为.orig.bag )。如果备份文件已存在(并且未指定-f选项),则该工具将不会重新索引该文件。

1.ros的xx.msg、xx.srv、xx.proto编译
2.CMake介绍及CMakeLists.txt文件编写
3.RTK定位原理和数据解析
堆和栈的区别——vector引发的思考
圆曲线拟合和多项式拟合

二、rosbag数据解析及可视化

1.新建节点

节点名称为demo:

ros::init(argc, argv, "demo");

2.构造订阅器:

ros::Subscriber perceptionSub_ = n.subscribe("/perception/obstacles", 1, obstaclesCallback);

3.设计回调函数,并打印相关信息:

void obstaclesCallback(const BinaryDataConstPtr &msg) {
  auto t1 = std::chrono::high_resolution_clock::now();
  ROS_INFO("obstaclesCallback");
  perception_index++;
  static double total_time = 0.0;
  perception::Objects objects;
  rosToProto(*msg, objects);
  double obj_time = objects.header().stamp().sec() + objects.header().stamp().nsec() * 1e-9;
  int objs_num = objects.objs_size();
  updateObstacles(&objects);
  auto t2 = std::chrono::high_resolution_clock::now();
  double cost_time = std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count() / 1.0e9;
  total_time += cost_time;
  ROS_INFO(
      "Index: %ld, obj_time: %.3lf, obj_num: %d, cost_time: %.6lf, average_time: %.6lf",
      perception_index, obj_time, objs_num, cost_time, total_time / perception_index);
}

4.存储障碍物信息

void updateObstacles(perception::Objects *objects) {
  auto t1 = std::chrono::high_resolution_clock::now();
  obstacles_container_.append(objects);
  auto t2 = std::chrono::high_resolution_clock::now();
  auto timecost =
      std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count() / 1.0e9;  
  ROS_INFO("updateObstacles timecost: %.6lf", timecost);
}

5.可视化障碍物信息

void Visualization::drawTrajectory(ObstaclesContainer &obstacles_container, double current_time,
                                   GlobalToLocal &global_to_local,
                                   ROS_PUBLISHER(ROS_MSGS(visualization_msgs, MarkerArray)) &
                                       obj_trajectory) {
  ROS_MSGS(visualization_msgs, MarkerArray) marker_array;
  int marker_id = 0;
  static int last_marker_size = 0;
  ROS_MSGS(visualization_msgs, Marker) marker;
  marker.action = marker.ADD;
  marker.header.stamp = ros::Time::now();
  marker.header.frame_id = "base_link";
  marker.ns = "obj_trajectory";
  marker.type = marker.LINE_STRIP;
  // marker.type = ROS_MSGS(visualization_msgs, Marker)::SPHERE;
  marker.pose.orientation.w = 1.0;
  marker.scale.x = 0.4;
  marker.scale.y = 0.4;
  marker.scale.z = 0.4;
  marker.color.r = 1.0;
  marker.color.b = 0.0;
  marker.color.g = 0.0;
  marker.color.a = 1.0;
  for (auto &p : obstacles_container) {
    auto index = p.second.upperBoundByTime(current_time);
    if (index > 0) {
      index -= 1;
    }
    auto &obj = p.second.at(index);
    auto t = ObstacleContainer::getTimeFromTrackedObject(&obj);
    auto abs_t = std::abs(t - current_time);
    if (abs_t < 0.01) {  // 当前帧存在
      // 可视化
      marker.id = marker_id++;
      ROS_MSGS(geometry_msgs, Point) point;

      drawBBox(marker, obj.obj().size());
      double heading = obj.obj().angle();
      ROS_MSGS(geometry_msgs, Quaternion) quaternion;
      quaternion.z = sin(heading / 2);
      quaternion.w = cos(heading / 2);
      marker.pose.orientation = quaternion;
      marker.pose.position.x = obj.longitude_p();  // UTM
      marker.pose.position.y = obj.latitude_p();
      global_to_local.transform(marker.pose.position.x, marker.pose.position.y);
      marker_array.markers.emplace_back(marker);
      marker.points.clear();

      marker.id = marker_id++;
      marker.pose.orientation.z = 0.0;
      marker.pose.orientation.w = 1.0;
      marker.pose.position.x = 0;
      marker.pose.position.y = 0;

      int path_point_size = 50;
      for (int k = 0; k < path_point_size; k++) {
        auto &obj = p.second.at(index);
        point.x = obj.longitude_p();  // UTM
        point.y = obj.latitude_p();
        global_to_local.transform(point.x, point.y);
        marker.points.push_back(point);
        if (index == 0) break;
        --index;
      }
      marker_array.markers.emplace_back(marker);
      marker.points.clear();
    }
  }
  int id_temp = marker_id;
  while (marker_id < last_marker_size) {
    marker.id = marker_id++;
    marker.action = marker.DELETE;
    marker_array.markers.emplace_back(marker);
  }
  if (id_temp < last_marker_size)
    last_marker_size = id_temp;
  else
    last_marker_size = marker_array.markers.size();
  ROS_PUBLISH(obj_trajectory, marker_array);
}

6.障碍物数据可视化效果

如下图所是,可视化了历史轨迹和box。
在这里插入图片描述下图为算法耗时,0.3ms左右。
在这里插入图片描述

总结

本文介绍了rosbag相关知识,并基于rosbag数据进行障碍物数据解析和可视化。实际上分别写了模块组件类、容器类、可视化类等,算法架构设计花了不少时间,可视化不太熟悉,浪费了点时间,后面可能不能天天更新了,时间有限。

标签:obj,msgs,Rosbag,bag,实例,time,marker,解析,rosbag
From: https://blog.csdn.net/c15901088098/article/details/141199085

相关文章

  • 深入解析Objective-C中NSParagraphStyle的段落样式处理艺术
    标题:深入解析Objective-C中NSParagraphStyle的段落样式处理艺术在Objective-C的世界中,文本排版是一个复杂但至关重要的话题。NSParagraphStyle作为其中的核心组件,扮演着决定文本段落外观和布局的关键角色。本文将深入探讨NSParagraphStyle的内部机制,并通过实际代码示例,展示......
  • Kubernetes中Pod间通信的详细解析
    目录同一个节点中Pod通信原理网络拓扑结构通信过程不同节点上的Pod通信原理网络拓扑结构通信过程同一个节点中Pod通信原理网络拓扑结构Pod:每个Pod都有一个唯一的IP地址(例如,172.16.3.2和172.16.3.3)。Pod内部的网络接口(eth0)连接到一个虚拟网络设备(veth)。虚拟网络设备(vethp......
  • 深入浅出 CDN 链接:从原理到应用,全面解析内容分发网络
    深入浅出CDN链接:从原理到应用,全面解析内容分发网络CDN(ContentDeliveryNetwork,内容分发网络)是近年来互联网发展的重要基石,它通过将内容缓存到全球各地的服务器上,实现内容的快速、高效分发,提升用户体验,降低网站运营成本。本文将从CDN链接的原理、工作机制、应用场景、......
  • 博客建站6 - 一文搞懂域名解析(保姆级教程和原理讲解)
    1.本网站的系统架构2.(阿里云)域名解析配置2.1.快速配置2.2.自定义配置2.2.1.记录类型2.2.2.主机记录2.2.3.记录值2.2.4.解析请求来源3.域名解析原理3.1.什么是DNS3.2.DNS的解析原理3.2.1.1.本地查询3.2.2.2.客户机到服务器查询3.2.3.3.服务......
  • AQS解析
    关键信息state(volatile修饰)/双向链表数据结构AQS有那些实现?ReentrantLock、Semaphore、CountDownLatch AQS分为同步队列和条件队列publicclassBoundedBuffer<T>{   privatefinalLocklock=newReentrantLock();   privatefinalConditionnotFull=......
  • JSONUtil、JsonArray应用 (全网最全面的解析方式汇总) - 调用第三方接口后,获取的结果
    背景:近期开发的内容涉及到了我们平台对其他平台提供接口的调用,然后也涉及到接口提供方的验签等操作;还有我们的加签操作等。今天记录一下调用三方接口后返回的接口如何解析;怎么拿到自己想要的东西。其实调用三方接口分为几步1、采用哪种方式调用三方接口,这种依赖于第三方......
  • C语言中的操作符:深入解析与应用
    引言C语言提供了丰富的操作符,用于执行算术运算、逻辑判断、位操作等。这些操作符是编程语言中的基础构件,它们使得程序能够进行复杂的数据处理和逻辑控制。本文将详细介绍C语言中的各种操作符,包括它们的类型、用法和一些实际应用示例。操作符的分类算术操作符算术操作符用于......
  • Windows通过dynv6提供免费的IPv6动态域名解析(DDNS)服务(注册服务的方式运行)
    Dynv6IPv6Updater项目简介特性使用方法环境依赖运行脚本参数说明示例日志输出Windows服务注册步骤1:下载并安装NSSM步骤2:准备Python环境和脚本步骤3:使用NSSM注册服务步骤4:启动服务并验证步骤5:设置日志记录(可选)步骤6:重启系统并验证附:以下为帮......
  • 基于Nexus实现配置阿里云代理仓库过程解析
    基于Nexus实现配置阿里云代理仓库过程解析更新时间:2020年07月09日09:19:07  作者:咔咔kk 这篇文章主要介绍了基于Nexus实现配置阿里云代理仓库过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下Nexus默认远程仓......
  • ThreadLocal源码解析
    ThreadLocal有内部类ThreadLocalMap,ThreadLocalMap是ThreadLocal的核心1.每个线程下的有一个ThreadLocalMapstaticclassThreadLocalMap{staticclassEntryextendsWeakReference<ThreadLocal<?>>{Objectvalue;Entry(ThreadLocal<?>k,Ob......