LoginSignup
0
0

ros2のsetup.pyで入れ子(ネスト)のディレクトリもshareディレクトリに追加する方法

Last updated at Posted at 2024-01-21

お疲れ様です。秋並です。

今回は、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': [
        ],
    },
)

参考サイト

ROS 2 : Pythonでパッケージ作成するときのチップス

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0