ROS(ROS2) - python 初期化ファイル

クラウディア 
1. 概要
2. デフォルトの状態
3. 初期化ファイルの配置
4. setup.py
5. ソースの記述

1. 概要

 「python」のパッケージで、初期化ファイル「initial.json」というファイルを作成して。

パッケージ/MyClass/MyClass.py
 というクラスから、読み込ませたかったのです。  本ページは、下記のサイトを参考にさせていただきました。
ros2 の setup.py で入れ子(ネスト)のディレクトリも share ディレクトリに追加する方法 #Python
 本ページ、まだ、正解とまではいきませんが、とりあえず、初期化ファイルをインストールして、読込ができるところまで持っていけましたので、記述しておきます。

2. デフォルトの状態

 デフォルトの「setup.py」が、下記の状態ですな。

from setuptools import find_packages, setup

package_name = 'my_service'
submodules   = 'my_service/MyClass'

setup(
    name=package_name,
    version='0.0.0',
    packages=[ package_name, submodules ],
    packages=find_packages(exclude=['test']),
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='hogehoge',
    maintainer_email='hogehoge@todo.todo',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'server = my_service.my_server:main',
            'client = my_service.my_client:main',
        ],
    },
)
 これに、「initial.json」というモジュールを加えて、「install」先に持っていきたいわけです。

3. 初期化ファイルの配置

 パッケージのプログラムソースの構成は。

src/my_service/
|-- my_service
|   |-- __init__.py
|   |-- my_client.py
|   |-- my_server.py
|   `-- MyClass
|       `-- MyClass.py
|-- package.xml
|-- resource
|   `-- my_service
|-- setup.cfg
`-- setup.py
 となっております(不要な個所は、省略)。  「initial.json」は、下記へ配置することにしました。

src/my_service/my_service/serial/initial.json

4. setup.py

 「setup.py」を参考サイトを参考にしつつ、下記のように記述しました。

from setuptools import find_packages, setup
import os
from glob import glob

package_name = 'my_service'
submodules   = 'my_service/serial'

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('initial', data_files)

setup(
    name=package_name,
    version='0.0.0',
    packages=[ package_name, submodules ],
    data_files=data_files,
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='hogehoge',
    maintainer_email='hogehoge@todo.todo',
    description='TODO: Package description',
    license='TODO: License declaration',
    entry_points={
        'console_scripts': [
            'server = my_service.my_server:main',
            'client = my_service.my_client:main',
        ],
    },
)
 参考サイトと記述が異なるところがありますが、どうも、こうなっちゃうんだな。  2、3行目は、下で使用するモジュールのインポート。  8~17行目は、「initial」配下をインストールの配列に加えています。  23行目は、インストールモジュールを 8~17行で定義したものへ変更しています。  その他、「test」の記述を省略しています。  この結果、ビルドすると、「install」は、下記へ展開されます。

install/my_service/share/my_service/initial/
`-- initial.json
 「Windows」では、下記へ展開されます。

install\share\my_service\initial
    initial.json
 この辺、構成が異なるわけです。

5. ソースの記述


MyClass/MyClass.py
 のソースは、下記のように記述します。

import json5
import os
import platform
import re

class MyClass:

  # コンストラクタ
  def __init__(self):

    if platform.system() == 'Linux':
      inifile = os.path.dirname(__file__) + '/../../../../../share/my_service/initial/initial.json'
    else:
      inifile = os.path.dirname(__file__) + '\\..\\..\\..\\..\\share\\my_service\\initial\\initial.json'

    with open(inifile, encoding='utf-8') as f:
      self.config = json5.load(f)
 これで、16、17行で、「UTF-8」で記述した、「initial.json」の内容を読み取ることができます。
AbemaTV 無料体験
ネットオークションの相場、統計、価格比較といえばオークファン