0

我创建了一个自定义 ros 消息,其格式如下

# Header information
std_msgs/Header header

# Model
string model

# Data
uint8[] data

数据是从 csv 文件读取的 4D 列表列表

def createData(csv_file): 
     x,y,z,w = np.loadtxt(dataFile, usecols=(0,1,2,3), \ skiprows=0, delimiter="\t", unpack=True) 
     p = [] 
     for p1, p2, p3, p4 in zip(x,y,z,w): 
        pt = [p1, p2, p3, p4] 
        p.append(pt)
     header = Header()
     header.stamp = rospy.rostime.Time.from_sec(time.time())
     header.frame_id = "main_frame"
     model = "sensor"
     msg = customMessage(header, model, p)
     return msg, p

with rosbag.Bag('test.bag', 'w') as bag:
    msg, points = createData(csv_file)
    bag.write(topic_name, msg)
bag.close()

customMessage(genpy.Message)类里面,我设置了msg.datato pmsg.headertoheadermsg.modeltomodel 我用这个消息类型创建了一个随机数据,我试图写一个包文件出来

bag.write(topic_name, msg)

但是我收到此错误

Traceback (most recent call last):
  File "data2bag.py", line 306, in <module>
    bag.write(topic_name, msg)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/rosbag/bag.py", line 391, in write
    msg.serialize(self._buffer)
  File "data2bag.py", line 123, in serialize
    except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(locals().get('_x', self)))))
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/genpy/message.py", line 334, in _check_types
    check_type(n, t, getattr(self, n))
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/genpy/message.py", line 256, in check_type
    check_type(field_name+"[]", base_type, v)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/genpy/message.py", line 212, in check_type
    raise SerializationError('field %s must be unsigned integer type'%field_name)
genpy.message.SerializationError: field data[] must be unsigned integer type

msg.data一个类型<type 'list'>是假定的类型 如果只有msg.data有一个str类型,则包文件的写入成功

然而,这没有意义,因为它不会使用str数据类型

如果我通过以下方式将数据更改为 uint8:points = np.uint8(p)

我得到了这个错误

Traceback (most recent call last):
  File "data2bag.py", line 307, in <module>
    bag.write(topic_name, msg)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/rosbag/bag.py", line 391, in write
    msg.serialize(self._buffer)
  File "data2bag.py", line 123, in serialize
    except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(locals().get('_x', self)))))
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/genpy/message.py", line 334, in _check_types
    check_type(n, t, getattr(self, n))
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/genpy/message.py", line 254, in check_type
    raise SerializationError('field %s must be a list or tuple type'%field_name)
genpy.message.SerializationError: field data must be a list or tuple type

以前有人遇到过这样的问题吗?

我尝试更改数据读取方法

for p1, p2, p3, p4 in zip(x,y,z,w):
        pt = [int(p1), int(p2), int(p3), int(p4)]
        p.extend(pt)

但是我的 p1、p2、p3 和 p4 是浮动的,我只是做了 int cast 来尝试它。我得到了同样的错误

4

1 回答 1

0

我怀疑您列表中的元素类型不正确。没有看到你的代码就不可能说。这是一个最小的工作示例:

import rosbag
from std_msgs.msg import UInt8MultiArray
bag = rosbag.Bag('test.bag', 'w')

try:
    a = UInt8MultiArray()
    a.data = [1,2,3]
    bag.write('array', a)
finally:
    bag.close()

这工作正常。


根据您发布的代码进行更新。

我很确定您的列表包含字符串数组,这两个都是错误的。你希望它是平面和整数:

     p = [] 
     for p1, p2, p3, p4 in zip(x,y,z,w): 
        p.extend([int(p1), int(p2), int(p3), int(p4)])
于 2020-10-16T23:46:44.227 回答