ROS2 Python节点为何在install目录找数据?求解决方案
ROS2节点无法找到CSV文件的原因与解决办法
问题原因
- 路径获取逻辑错误:你用
os.path.dirname(__file__)获取文件路径,但ROS2编译后,Python节点会被部署到install目录下的site-packages中,此时__file__指向的是编译安装后的文件路径,而非src目录下的源码路径,导致拼接出的查找路径指向install目录,自然找不到src里的原始文件。 - 资源文件未配置安装规则:你没有在
package.xml和setup.py中声明资源文件的安装规则,编译过程中CSV文件不会被复制到install目录的对应位置,即便路径逻辑正确也找不到文件。
解决办法
1. 配置ROS2包的资源文件安装规则
修改package.xml
添加资源目录声明和依赖:
<!-- 声明资源目录 --> <resource_directory> <path>resource</path> </resource_directory> <!-- 添加依赖,用于获取包共享目录 --> <exec_depend>ament_index_python</exec_depend>
修改setup.py
在data_files中添加CSV文件的安装路径规则,确保编译时文件被复制到正确位置:
from setuptools import setup import os from glob import glob package_name = 'foo_package' setup( name=package_name, version='0.0.0', packages=[package_name], data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), # 将resource/data下的所有CSV文件安装到共享目录对应位置 (os.path.join('share', package_name, 'resource/data'), glob('resource/data/*.csv')) ], install_requires=['setuptools'], zip_safe=True, maintainer='Your Name', maintainer_email='your@email.com', description='Package description', license='License declaration', tests_require=['pytest'], entry_points={ 'console_scripts': [ 'your_node_name = foo_package.your_node_file:main', ], }, )
2. 修改文件读取逻辑,使用ROS2官方API获取路径
替换原有的get_file_location函数,用ament_index_python提供的get_package_share_directory获取包的共享目录,确保编译前后路径都正确:
from ament_index_python.packages import get_package_share_directory import os import csv import numpy as np class YourNodeClass: @staticmethod def get_file_location(filename, location='resource/data'): # 获取foo_package的共享目录路径 package_share_dir = get_package_share_directory('foo_package') directory_path = os.path.join(package_share_dir, location) return os.path.join(directory_path, filename) def read_data(self, filename, order=-1, dimensions=-1): file_path = self.get_file_location(filename) with open(file_path, 'r') as file: return self.read_file(file, order, dimensions) @staticmethod def read_file(file, order=-1, dimensions=-1): reader = csv.reader(file) data_list = list(reader) data_array = np.array(data_list).astype(np.float64) return data_array[:, order:order+dimensions] if order > -1 and dimensions > -1 else data_array
3. 开发阶段可选优化
如果在开发过程中不想每次修改文件都重新编译,可以使用符号链接编译:
colcon build --symlink-install
此命令会在install目录创建源码文件的符号链接,修改src里的CSV文件后无需重新编译即可生效。
内容的提问来源于stack exchange,提问作者Zain Ahmed
相关产品推荐
相关产品推荐

