解析topic报错UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0x8b in position 59: invalid start byte

查找bag解析报错:“UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0x8b in position 59: invalid start byte”

在针对指定topic执行解析bag包的时候,有的bag提示:UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0x8b in position 59: invalid start byte。
出问题的代码是ros的库文件:lib/python3.7/site-packages/rosbag/bag.py。然后进行debug:

方法1:找出bag中是否有非法的字符

首先了解编码/解码:为了显示特殊字符与汉字,会将其按照协议编码。如下例子:

	# 执行编码,查看'失败 123abc'会编成什么:
    byte_string = '失败 123abc'
    uni_string = repr(byte_string)
    print(uni_string)
    
    # 执行解码,查看字符会解码成什么:
    byte_string =b'\xe5\xa4\xb1\xe8\xb4\xa5'
    new_by_string = byte_string.decode('utf-8')
    print(new_by_string)

运行结果:

# '失败 123abc'会编码为如下。明显数字与英文不会被编码
'\xe5\xa4\xb1\xe8\xb4\xa5 123abc'
# b'\xe5\xa4\xb1\xe8\xb4\xa5'会被解码为中文:
失败

根据上边的例子,也就是说bag中有特殊字符解码错误。
在bag.py中添加调试代码,确实发现:\x98\xa8\xff\x86\xfa\x7f,这种无法解码的字符。但是查找发布topic的源码,并没有打印非法字符或者异常字符。

方法2:对比运行ok的镜像,查看问题原因。

恢复镜像的版本,执行ok,不会报错。对比问题镜像与ok的镜像。问题镜像中lib/python3.7/site-packages/rosbag/bag.py为2614行,ok的镜像中为2938行。明显不一致。所以猜测是rosbag库文件的问题,对于部分字符encode失败。

结论:rosbag库文件会导致encode报错。

后续:为了找出2个库中编码的区别,修改bag.py,将全部的data输出,将有0x98的地方都打印出来:

cat error_msg.txt | grep -o ".\{0,20\}x98.\{0,20\}"

查看二者的解析结果是否有区别。结果是没有区别的。这就有问题了。
取出ok镜像输出的任意几处编码:

b'\x93\x01\x00\x00^\xe4ed\x14\r\xb30\x00\x00\x00\x00\xe3\x00\x00\x00\x00A\x00\x00\x00[INF]'
b'\x98\x01\x00\x00_\xe4ed\xe6\x90\xbf\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01/\x00\x00\x00 p'

执行解码:

    byte_string = b'\x98\x01\x00\x00_\xe4ed\xe6\x90\xbf\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01/\x00\x00\x00 p'
    new_by_string = byte_string.decode('utf-8')

结果还是报错:

UnicodeDecodeError: 'utf8' codec can't decode byte 0x98 in position 0: invalid start byte

查找资料,说这些二进制文件并不是可以编码解码的内容。可能是 ROS Bag 文件格式中的 Index Data(索引数据)或者 Connection Header(连接头)等二进制数据。这些数据是以机器人操作系统 (ROS) 中定义的二进制格式存储的,并不是文本字符串形式。

具体来说,Index Data 是指用于记录 ROS Bag 中所有消息的位置、时间等元数据的数据结构。而 Connection Header 则是指在 ROS 中用于描述话题通信方式和参数的字典数据结构。这些数据都是以 C++ 语言定义的二进制格式存储的,因此并不能直接使用 Python 或其他编程语言的字符串解码方法进行解析。

因此结论就是:出问题的镜像中,将rosbag中的二进制数据当作可以解码的数据,因此报错。而新的镜像中解决了这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值