ROS2: 別のpythonファイルからインポートしてノードをつくる手順
海洋ロボコンをやってた人です。
今回は、pythonでROS2ノードをつくるときに、別のPythonファイルからクラスや関数をインポートするときの記述方法について知見をまとめておきます。
経緯としては、pythonで書かれたROS2プログラムに、別のpythonファイルの関数を読み込む方法が記事にまとまっておらず、わからないという意見を頂いたためです。
なお、本記事はROS2でpythonを使ったプログラムを書く必要性がある方を対象としており、C++でのプログラムで良い場合は依存関係の観点からも、C++での記述が良いと思います。
この記事が皆様のお力添えになれば幸いです。
※2023/02/26追記: 本記事の「ROS2」表記、正しくは「ROS 2」です。
別のpythonファイルからインポートしてROS2ノードをつくる
今回は、以下のようなpython-ROS2パッケージを想定しており、robot_controlパッケージのrobot_control/control_modules/flapping_driver.pyをrobot_control/wing_motion_node.pyにインポートする方法を参考例として紹介していきます。
robot_control/
├ package.xml
├ setup.cfg
├ setup.py
├ test/
├ launch/
├ resource/
├ robot_control/
├ __init__.py
├ wing_motion_node.py
├ control_modules/
├ __init__.py
├ flapping_driver.py
そのため、インポートしたい外部のpythonファイルは任意のフォルダ下に配置してください。
*ここでは"robot_control/control_modules/フォルダのこと
外部pythonファイルのクラス化とROS側でのインポート記述
まずは、python-ROS2プログラムにインポートしたい外部のpythonファイルでクラスを定義していきます。
import math
class Flapping(object):
def __init__(
self, period=None, down_freq=None, \
):
self.period = period
def create_flapping_angle():
上記では、Flappingというクラスを定義しました。
続いて、ROS2側のpythonプログラムで外部のpythonプログラムをインポートしていきます。
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Joy
from sensor_msgs.msg import JointState
from .control_modules.flapping_driver import *
import time
import math
class WingMotionParam():
def __init__(self):
# Create the motion of the flapping wing
flapping = Flapping(period=2.5, down_freq=0.43)
python-ROS2側では、
- from .control_modules.flapping_driver import *
と記述することで、control_modules下のflapping_driverのクラスや関数をインポートすることができます。
なお、ここでは"import *"という表記ですが、クラスが単一の場合は"import Flapping"という表記でも問題ありません。
setup.pyにsubmodulesとしてパッケージを追加する
外部のpythonファイルのインポート記述ができたら、setup.pyにsubmodulesとしてパッケージの依存関係を追加します。
ros2_pkg_createでパッケージを作るとpackage_nameという宣言があるので、その下にsubmodulesという形で外部のpythonファイルディレクトリを宣言します。
その後、setup部分でpackagesのリスト部分に"submodules"を追加すれば完了です。
ここの情報がかなり乏しいようですね。
from setuptools import setup
from glob import glob
import os
package_name = 'robot_control'
+ submodules = 'robot_control/control_modules'
setup(
name=package_name,
version='0.0.0',
+ packages=[package_name, submodules],
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
(os.path.join('share',package_name), glob('launch/*.py'))
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='',
maintainer_email='',
description='',
license='',
tests_require=['pytest'],
entry_points={
'console_scripts': [
],
},
)
これで、別のpythonファイルから、プログラムをインポートして使えるようになるはずです。
この記事が少しでも、皆様のお役に立てば幸いです。
また、"いいね"をいただけますと、非常にモチベーションに繋がります(´・ω・`)
以上。
Discussion