LoginSignup
4
2

【ROS2/Python】RyeをROS2で使う

Last updated at Posted at 2023-11-30

はじめに

本記事は、ROS2アドベントカレンダー1日目の記事です!

今回はPythonパッケージ管理ソフトウェアのRyeをROS2で使った例を示そうと思います。

ROS2×Pythonパッケージ管理ソフトウェアについての意見は様々あります。本記事も一例としてとらえてください。

環境

以下の環境で動作を確認しています。

項目 バージョン
Ubuntu 22.04
ROS2 Humble

手順

簡単に手順を説明すると以下です。

  • Ryeをインストールする
  • ROS2のパッケージを作成する (PythonのROSノードですが、ビルド方法はament_cmakeを選択)
  • パッケージのディレクトリ内でRyeの設定を行う
  • ソースコードを作成する
  • ビルドする
  • Ryeの環境に入り、ros2 run コマンドでPythonファイルを実行する

記事内では上記について説明しますが、ソースコードは以下にあるので実行したい方はREADME通りにコマンドを実行していくとRye上でROSノードの動作確認までできます。

Ryeをインストールする

curl -sSf https://rye-up.com/get | bash
echo 'source "$HOME/.rye/env"' >> ~/.bashrc

参考:
https://rye-up.com/guide/installation/#installing-rye

ROS2のパッケージを作成する

今回はパッケージ名を rye_sample_pkgとします。

ros2 pkg create rye_sample_pkg --license MIT

自動的に生成されるファイルは以下のようになります。
PythonのROSノードを作成しますがament_cmakeを使用するためCMakeLists.txt等があって問題ありません。

rye_sample_pkg/
  ├ CMakeLists.txt
  ├ LICENSE
  ├ include/
    ├ rye_sample_pkg
  ├ package.xml
  ├ src/

パッケージのディレクトリ内でRyeの設定を行う

cd ~/ros2_ws/rye_sample_pkg
rye init

以下のように、READMEやpyproject.xmlが自動生成されます。

rye_sample_pkg/
  ├ CMakeLists.txt
  ├ LICENSE
  ├ README.md
  ├ include/
    ├ rye_sample_pkg
  ├ package.xml
  ├ pyproject.tom
  ├ src/

rye pinコマンドで、そのディレクトリ内で作成されるPythonのbinファイルのバージョンを指定できます。rclpy等ROS2のソフトウェアは/opt/ros/配下のものを使用するのでPythonのメジャーバージョンはUbuntu本体のものと合わせましょう。
その後、rye syncコマンドで環境が作成されます。

rye pin 3.10
rye sync

ディレクトリ構成は以下のようになり、requirements*ファイルが自動生成されます。

rye_sample_pkg/
  ├ CMakeLists.txt
  ├ LICENSE
  ├ README.md
  ├ include/
    ├ rye_sample_pkg
  ├ package.xml
  ├ pyproject.tom
  ├ src/
  ├ requirements-dev.lock
  ├ requirements.lock

ソースコードを作成する

名称は問わないですが今回は scriptsディレクトリを作成してその中にソースコードを作成しましょう。

mkdir scripts
cd scripts
vi talker.py

ROS2の以下のページを参考に作成します。
https://docs.ros.org/en/foxy/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Py-Publisher-And-Subscriber.html

#/usr/bin/env python3
import rclpy
from rclpy.node import Node
import sys

from std_msgs.msg import String


class MinimalPublisher(Node):

    def __init__(self):
        super().__init__('minimal_publisher')
        self.get_logger().info(f"python path: {sys.executable}")
        self.publisher_ = self.create_publisher(String, 'topic', 10)
        timer_period = 0.5  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = String()
        msg.data = 'Hello World: %d' % self.i
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.i += 1


def main(args=None):
    rclpy.init(args=args)

    minimal_publisher = MinimalPublisher()

    rclpy.spin(minimal_publisher)

    # Destroy the node explicitly
    # (optional - otherwise it will be done automatically
    # when the garbage collector destroys the node object)
    minimal_publisher.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

また、talker.pyに実行権限をつけましょう。CMakeの設定でPythonファイルをインストールするためです。

sudo chmod +x talker.py

ros2 のノードのために必要な __init__.pyを作成しましょう。

mkdir rye_sample_pkg
cd rye_sample_pkg
touch __init__.py

CMakeLists.txtにPythonのインストールの設定を追記しましょう。

cmake_minimum_required(VERSION 3.8)
project(rye_sample_pkg)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(ament_cmake_python REQUIRED)
find_package(rclpy REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
ament_python_install_package(${PROJECT_NAME})
install(PROGRAMS scripts/talker.py DESTINATION lib/${PROJECT_NAME})

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

ビルドする

いつも通り colcon buildでビルドしましょう。
CMakeListsで設定した通り、install/rye_sample_pkg/lib/rye_sample_pkg/配下にtalker.pyがコピーされたら成功です。

colcon build --packages-select rye_sample_pkg --symlink-install

ROSノードを実行する

Ryeの環境内に入った後にros2 runでROSノードを起動するとryeの環境でROSノードが立ち上がります。

cd ~/ros2_ws/src/rye_sample_pkg
rye shell
ros2 run rye_sample_pkg talker.py
[INFO] [1700807070.570010760] [minimal_publisher]: python path: /home/koichi/ros2_ws/src/rye_sample_pkg/.venv/bin/python3
[INFO] [1700807071.071507709] [minimal_publisher]: Publishing: "Hello World: 0"
[INFO] [1700807071.573184340] [minimal_publisher]: Publishing: "Hello World: 1"
[INFO] [1700807072.072772997] [minimal_publisher]: Publishing: "Hello World: 2"
[INFO] [1700807072.572920468] [minimal_publisher]: Publishing: "Hello World: 3"

Ryeの使い方

今更ですが、Ryeの使い方を簡単に紹介します。

プロジェクトへパッケージの追加

rye add XXX
# 例
rye add numpy
rye add tensorflow

パッケージの削除

rye remove XXX
# 例
rye remove numpy

上記のコマンドは、pyproject.tomlファイルを操作するだけで実際のインストール/アンインストールは行われません。それらを実行するには下記を実行します。

パッケージのインストール/アンインストール

rye sync

ryeの環境に入る

上記で、requirements*や、 .venvなどが生成されます。
以下のコマンドでryeの実行環境に入ることができます。

rye shell
# または
. .venv/bin/activate

ROS2での使い方

Poetryなどはワークスペースごと or モノレポで管理されているプロジェクトを一括で管理する際に有用だったと思っています。
それに比べてRyeはパッケージごとにPythonの仮想環境まるごと使い分けることが可能ではあるので、そこは差別化できるのかと思いました。

おわりに

ROS2に限らず、Pythonのパッケージ管理方法に正解はなさそうなのでこれからも慎重に向き合っていきましょう!

アドベントカレンダー、盛り上がっていきましょう!

4
2
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
4
2