お疲れ様です。秋並です。
今回は、ros2でpython用のパッケージを作成する際にsetup.pyの記述で詰まったところがあったので、その解決方法について解説します。
前提
ros2のワークスペースでpython用パッケージを作成する手順が分かっている。
実行環境
ubuntu22.04
ros2 humble
setup.pyでshareディレクトリにデータを追加する際に
meshes/dae
のような入れ子構造になったディレクトリを追加したい時があると思います。
package_name
|
---meshes
|
---dae
|--- OOO.dae
|--- ***.dae
デフォルトのsetup.pyに従って以下のように記述するとエラーが発生します。
例えば、以下のように meshes/dae
以下のファイルを指定した場合 error: can't copy 'meshes/dae': doesn't exist or not a regular file
というエラーが発生します。
from setuptools import setup
import os
from glob import glob
package_name = 'package_name'
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']),
(os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')),
(os.path.join('share', package_name, 'urdf'), glob('urdf/*')),
(os.path.join('share', package_name, 'meshes'), glob('meshes/*')),
(os.path.join('share', package_name, 'meshes/dae'), glob('meshes/dae/*')), # この箇所が上手く反映されず「error: can't copy 'meshes/dae': doesn't exist or not a regular file」とエラーが発生する
(os.path.join('share', package_name,
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='author',
maintainer_email='todo@todo.com',
description='The ' + package_name + ' package',
license='TODO: License declaration',
tests_require=['pytest'],
entry_points={
'console_scripts': [
],
},
)
これを改善するには、以下のように記述するとよいです。
from setuptools import setup
import os
from glob import glob
package_name = 'package_name'
data_files = []
data_files.append(("share/ament_index/resource_index/packages", ["resource/" + package_name]))
data_files.append(("share/" + package_name, ["package.xml"]))
def package_files(directory, data_files):
for (path, directories, filenames) in os.walk(directory):
for filename in filenames:
data_files.append(("share/" + package_name + "/" + path, glob(path + "/**/*.*", recursive=True)))
return data_files
data_files = package_files('launch/', data_files)
data_files = package_files('urdf/', data_files)
data_files = package_files('meshes/', data_files)
data_files = package_files('meshes/dae', data_files) # これの場合、エラーが出ない
setup(
name=package_name,
version='0.0.0',
packages=[package_name],
data_files=data_files,
install_requires=['setuptools'],
zip_safe=True,
maintainer='author',
maintainer_email='todo@todo.com',
description='The ' + package_name + ' package',
license='TODO: License declaration',
tests_require=['pytest'],
entry_points={
'console_scripts': [
],
},
)