【安装学习】ROS rqt_graph保存.dot文件TypeError错误解决方案

问题描述

在ROS Noetic中使用rqt_graph保存.dot类型的话题链接情况文件时,出现以下错误:

1
2
3
4
5
zhao@zhao:~/WS/Now/demo_ws$ rosrun rqt_graph rqt_graph 
Traceback (most recent call last):
File "/opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py", line 414, in save_dot
handle.write(self._current_dotcode)
TypeError: write(self, Union[QByteArray, bytes, bytearray]): argument 1 has unexpected type 'str'

问题特征

  • 保存默认名称frames.dot可以正常工作
  • 保存自定义名称LIO-SAM-Debug-Active.dot时出现错误
  • 保存的文件无法正确打开

问题根本原因

1. 编码类型不匹配

在ROS Noetic(Python 3)中,write()方法期望接收字节类型数据(bytesbytearrayQByteArray),但实际接收到的是字符串类型(str)。

根本原因

  • Python 3对字符串和字节的处理更加严格
  • self._current_dotcode是字符串类型
  • 文件句柄的write()方法期望字节类型数据

2. 文件名特殊字符影响

初步怀疑是文件名中的连字符(-)导致的问题,但实际上主要是编码转换问题。

验证方法

1
2
3
4
# 测试不同文件名
frames.dot # ✓ 正常
LIO-SAM-Debug-Active.dot # ✗ 报错
LIO_SAM_Debug_Active.dot # ✗ 同样报错(如果未修复编码问题)

解决方案

方案一:源码修改(推荐)

1. 备份原文件

1
sudo cp /opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py /opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py.bak

2. 修改源代码

1
sudo nano /opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py

3. 找到第414行,进行修改

原代码:

1
handle.write(self._current_dotcode)

修改为:

1
handle.write(self._current_dotcode.encode('utf-8'))

方案二:更完整的修改(避免潜在问题)

如果需要更安全的修改,可以添加类型检查:

1
2
3
4
if isinstance(self._current_dotcode, str):
handle.write(self._current_dotcode.encode('utf-8'))
else:
handle.write(self._current_dotcode)

注意事项

  • 保持原有的缩进格式,避免TabError
  • 如果文件使用制表符缩进,修改时也要使用制表符
  • 如果文件使用空格缩进,修改时也要使用空格

调试过程中的错误

TabError: inconsistent use of tabs and spaces

在修改过程中遇到的缩进错误:

1
TabError: inconsistent use of tabs and spaces in indentation

解决方法

  1. 恢复备份文件
  2. 使用与原文件相同的缩进方式
  3. 检查编辑器设置,确保制表符和空格一致

检查缩进方式

1
2
# 查看文件缩进类型
sed -n '410,420p' /opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py | cat -A

验证修复

测试步骤

1. 基本功能测试

1
rosrun rqt_graph rqt_graph

2. 文件名测试

1
2
3
4
5
# 测试各种文件名
frames.dot # 默认名称
test.dot # 简单名称
LIO_SAM_Debug_Active.dot # 下划线分隔
LIO-SAM-Debug-Active.dot # 连字符分隔

3. 文件内容验证

1
2
3
4
5
# 检查生成的.dot文件内容
cat your_file.dot

# 使用graphviz生成图像
dot -Tpng your_file.dot -o output.png

文件命名建议

虽然编码问题已解决,但为了避免潜在的兼容性问题,建议:

推荐的文件命名规范

1
2
3
4
5
6
7
8
9
# 推荐使用
LIO_SAM_Debug_Active.dot
rqt_graph_output.dot
robot_tf_graph.dot

# 避免使用
LIO-SAM-Debug-Active.dot # 连字符可能在某些系统中引起问题
空格 文件名.dot # 空格需要转义
特殊字符@#$.dot # 特殊字符可能引起解析问题

替代方案

使用命令行工具

如果不想修改源码,可以使用ROS的命令行工具:

1
2
3
4
5
6
7
8
9
# 查看当前节点和话题
rosnode list
rostopic list

# 生成节点图(需要先安装graphviz)
rosrun rqt_graph rqt_graph_cmd --output=/tmp/graph.dot

# 手动转换为图片
dot -Tpng /tmp/graph.dot -o /tmp/graph.png

重新安装

如果修改出现问题,可以重新安装:

1
2
sudo apt update
sudo apt install --reinstall ros-noetic-rqt-graph

问题分析总结

技术原因

  1. Python 2 → Python 3 迁移遗留问题:ROS Noetic使用Python 3,对字符串处理更严格
  2. Qt文件处理接口变化:Qt的文件写入接口期望字节类型数据
  3. 编码转换缺失:源码中未处理字符串到字节的转换

解决思路

  1. 直接修复:在写入前进行编码转换
  2. 类型检查:添加类型判断以提高兼容性
  3. 频率对齐:确保文件操作的一致性

最佳实践建议

开发建议

  1. 备份重要文件:修改系统文件前务必备份
  2. 渐进测试:从简单测试开始,逐步验证功能
  3. 记录修改:详细记录修改内容和原因

系统维护

  1. 定期更新:关注ROS官方更新,此类问题可能在后续版本中修复
  2. 环境一致性:确保开发环境与部署环境一致
  3. 文档记录:将解决方案记录在项目文档中

总结

这个问题的核心是ROS Noetic中Python 3对字符串和字节类型的严格区分。通过简单的编码转换(encode('utf-8'))即可解决。

关键要点

  • 问题出现在字符串到字节的类型转换上
  • 文件名的特殊字符不是主要原因
  • 修改时要注意保持原有的缩进格式
  • 建议在修改前备份原文件

修复后的效果

  • 可以正常保存各种文件名的.dot文件
  • 生成的文件可以正确打开和处理
  • 不再出现TypeError错误

Reference