PointCloud2 存储格式

问题描述

我正在尝试在 FPGA 中实现 PointCloud2 消息的 ROS 发布节点。作为第一步,我已经在 FPGA 上实现了发布字符串的发布节点。现在,我正在尝试为 PointCloud2 消息格式做同样的事情。

理解一个字符串的存储方式非常简单,基本上每个字符都被转换成它的ASCII值并存储起来(可以看到here)。另一方面,PointCloud2 是一种复杂的数据类型,不容易理解。

我在理解 PointCloud2 的元数据如何存储方面取得了一些进展,但是,理解 PointCloud2 数据类型的数据部分的存储非常困难。为简化起见,我还尝试了只有一个点的 PointCloud2,但我也无法对其进行解码。我知道 X、Y 和 Z 是按顺序排列的,每个有 4 个字节(数据类型是 Float32)。因此,我可以隔离与坐标之一对应的 4 个字节。我试图将 0 到 17(十进制)的值分配给 X 坐标。这是使用这些值时存储的值(它们都是十进制的):

1 = [0,128,63] -> little-endian 所以,最高有效字节是 63,后面跟着,0

2 = [0,64]

3 = [0,64,64]

4 = [0,64]

5 = [0,160,64]

6 = [0,192,64]

7 = [0,224,64]

8 = [0,65]

9 = [0,16,65]

10 = [0,32,65]

11 = [0,48,65]

12 = [0,65]

13 = [0,80,65]

14 = [0,96,65]

15 = [0,112,65]

16 = [0,65]

17 = [0,136,65]

那么,我的问题是,这些值是如何存储的?假设数据部分根据 here 存储在二进制 blob 中。但是,我不明白这是什么意思以及它是如何工作的。另外,我还没有找到任何关于如何将十进制值转换为这种表示形式的具体示例。

对于带有 X、Y 和 Z 的 PointCloud2,我目前的理解如下(here 是相应的数据):

标题

  • seq(4 个字节)
  • 邮票(8 个字节)
  • frame_id(每个字符 1 个字节)

高度:4 字节

宽度:4 字节

字段:

  • 字段数(4 个字节)

字段 1

  • 维度(4 个字节)
  • 名称(1 个字节)
  • 偏移量(4 个字节)
  • 数据类型(1 个字节)
  • 计数(4 个字节)

字段 2

  • 维度(4 个字节)
  • 名称(1 个字节)
  • 偏移量(4 个字节)
  • 数据类型(1 个字节)
  • 计数(4 个字节)

字段 3

  • 维度(4 个字节)
  • 名称(1 个字节)
  • 偏移量(4 个字节)
  • 数据类型(1 个字节)
  • 计数(4 个字节)

is_bigendian:1 字节

point_step:4 个字节

row_step:4 个字节

大小:4 字节

数据:大小字节

is_dense:1 字节

解决方法

当我选择数据类型 7 (FLOAT32) 时,数据部分按照标准 IEEE 754(这是一种广泛使用的有效存储浮点数的标准)中的指示进行存储。幸运的是,已经有一个 Xilinx IP(浮点运算符)来处理浮点数,包括从其他类型(如 INT32)和数学运算(如乘法)的转换。