PR

ロボット制御 #14 ROS2 Jazzy を学ぶ
ROS2 Jazzy Jalisco のチュートリアルのパッケージ作成までやってみた話。

制御

前回、以下の記事でROS2 Jazzy をRaspberry Pi 5 にインストールして、初心者(CLI)チュートリアルを行いました。今回は、自分のプロジェクトが作れるようにクライアントライブラリについて勉強します。

教科書は、公式ROSドキュメントサイトです。

では、早速初めていきます。

パッケージのビルドに「colcon」を使用する

これは、「colcon」を使用して ROS 2 ワークスペースを作成および構築する方法に関する簡単なチュートリアルです。これは実践的なチュートリアルであり、コアドキュメントに代わるものではありません。

colcon」は、ROSビルドツールの「catkin_make」、「catkin_make_isolated」、「catkin_tools」、「ament_tools」を繰り返し実行します。設計の詳細については、このドキュメントを参照してください。

ソースは、以下にあります。

「colcon」をインストールする

ROS2 Jazzy をソースからビルドしたので既にインストールされていました。

ワークスペースを作成する

まず、ワークスペースを格納するディレクトリ「ros2_ws」を作成します。
ワークスペースの中には、複数のプロジェクトが格納できるように、プロジェクトディレクトリを作成します。

この時点で、ワークスペースには、1つの空の「src」ディレクトリが含まれています。

ソースを追加する

サンプルリポジトリをワークスペースの「src」ディレクトリにクローンしてみます。

これで、ワークスペースにROS2のサンプルのソースコードがダウンロードされます。

アンダーレイの入手

サンプル パッケージに必要なビルド依存関係をワークスペースに提供する既存の ROS 2 インストールの環境をソース化しておくことが重要です。これは、バイナリ インストールまたはソース インストール (つまり、別の colcon ワークスペース) によって提供されるセットアップ スクリプトをソース化することによって実現されます。

ちょっと表現が分かり難いですが、インストール時に作成したワークスペースを「source」しておくということです。

自分の場合は、インストール後に既に「~/.bashrc」に上記のコードを書いているので、自動的にアンダーレイが有効になっています。

ワークスペースを構築する

ワークスペースのルートで、 「colcon build」を実行します。 「ament_cmake」などのビルドタイプは「devel」スペースの概念をサポートしておらず、パッケージをインストールする必要があるため、colcon は、「--symlink-install」オプションをサポートしています。これにより、「source」スペース内のファイル (Python ファイルやその他のコンパイルされていないリソースなど) を変更することで、インストールされたファイルを変更し、反映処理を高速化できます。

ここは、難解な一文ですが、次のコマンドを入力してビルドします。

ビルドが完了すると「build」、「install」、「log」ディレクトリが表示されます。

テストを実行する

先ほど作成したパッケージのテストを実行するには、次のコマンドを実行します。

環境のソース

colcon が正常にビルドを完了すると、出力は、「install」ディレクトリに保存されます。インストールされた実行可能ファイルまたはライブラリを使用する前に、それらをパスとライブラリ パスに追加する必要があります。colcon は、「install」環境の設定に役立つ bash/bat ファイルをディレクトリに生成します。これらのファイルは、パスとライブラリ パスに必要なすべての要素を追加するとともに、パッケージによってエクスポートされた bash またはシェル コマンドを提供します。

デモを試す

環境がソース化されると、colcon によってビルドされた実行ファイルを実行できます。サンプルからサブスクライバーノードを実行してみます。

別のターミナルで、パブリッシャー ノードを実行してみましょう (セットアップ スクリプトをソースすることを忘れないでください)。

パブリッシャーとサブスクライバーからのメッセージが表示され、数字が増加していきます。

以降の内容は、少し難しいので、あまり理解できませんでした。
実際にやってみないと分からないですね。

独自のパッケージを作成する方法

colcon は、「REP 149」形式で定義された「pakage.xml」の仕様を使用します。(「REP 140」もサポートされています。)

colcon は複数のビルド タイプをサポートしています。推奨されるビルド タイプは、「ament_cmake」と「ament_python」です。純粋な「cmake」パッケージもサポートされています。

ament_python」のビルド例としては、「ament_index_python」パッケージがあります。ここでは、「setup.py」がビルドの主なエントリ ポイントです。

demo_nodes_cpp」などのパッケージは、「ament_cmake」のビルドタイプを司代油脂、ビルドツールとして「CMake」を使用します。

ros2 pkg create」というツールを使用してテンプレートに基づいた新しいパッケージを作成することもできます。

※ここは、概要の説明のみです。後で実際のパッケージを作ってみることになります。

「colcon_cd」の設定

colcon_cd」コマンドを使用すると、シェルの現在の作業ディレクトリをパッケージのディレクトリにすばやく変更できます。例えば、「colcon_cd some_ros_package」を入力すると、「~/ros2_ws/src/some_ros_package」ディレクトリにすばやく移動できます。

インストール方法やワークスペースの場所によっては、上記の手順が異なる場合があります。これを元に戻すには、システムのシェル起動スクリプト(~/.bashrc)を見つけて、追加されたソース コマンドとエクスポート コマンドを削除します。

補完機能を有効にする

colcon」をソースからビルドしてインストールした場合は、bashおよびbash-likeなシェルのコマンド補完をサポートします。これを使用するためには、「colcon_argcomplete.bash」をソースしておく必要がありますが、自分の環境では、想定の場所(/usr/share/colcon_argcomplete/hook)にインストールされていませんでした。
※補完機能の使用は断念しました。

その他のTips

  • 特定のパッケージをビルドしたくない場合は、「COLCON_IGNORE」ディレクトリに名前の付いた空のファイルを置くと、インデックスが作成されません。
  • CMake パッケージでテストの構成とビルドを避けたい場合は、「--cmake-args -DBUILD_TESTING=0」を渡すことができます。
  • パッケージから特定のテストを 1 つだけ実行する場合:

ワークスペースの作成

環境設定

メインのROS2をインストールした環境が、このチュートリアルのアンダーレイになります。(アンダーレイは必ずしもメインのROS2インストールである必要はないとのこと)
アンダーレイのシェルをソースする必要があります。

自分は、既に「~/.bashrc」に埋め込んでいるので必要ないです。

新しいディレクトリを作成する

一番簡単なワークスペースの管理方法は、新しいワークスペースごとに新しいディレクトリを作成することです。ここではチュートリアル用のワークスペースを新たに作成します。

これで先に作成していた「exsamples」ワークスペースと干渉せずに進めることが出来ます。

サンプルリポジトリをクローンする

チュートリアル用のリポジトリが用意されているのでクローンします。

以下の内容でクローンが作成されました。

このチュートリアルは、「turtlesim」が題材なんですね。

依存関係を解決する

ワークスペースでビルドする前に、パッケージの依存関係を解決する必要があります。既に全ての依存関係が解決されているかもしれませんが、長い待ち時間の挙句、ビルドが失敗するのは辛いので、クローンを作成するたびに依存関係を確認しておくことが望ましいです。

ワークスペースのルート「~/ros2_ws/tutorials/」から、次のコマンドを実行します。

既に全ての依存関係がある場合、コンソールは次を返します:

colcon でワークスペースを構築する

ワークスペースのルート「~/ros2_ws/tutorials/」から、次のコマンドを使用してパッケージをビルドします。

ビルドが完了したら、「exsamples」と同じように4つのディレクトリが出来ています。

オーバーレイのソース

オーバーレイをソースする前に、ワークスペースをビルドしたターミナルとは別の新しいターミナルを開く必要があります。ビルドしたのと同じターミナルでオーバーレイをソースしたり、オーバーレイがソースされた場所で同様にビルドしたりすると、複雑な問題が発生する可能性があります。

新しいターミナルで、メインのROS2 環境を「アンダーレイ」としてソースし、その「上に」オーバーレイを構築できるようにします。
なお、自分は、起動スクリプトでアンダーレイはソースしているので、オーバーレイのみソースします。

オーバーレイの「local_setup」をソースすると、オーバーレイで使用可能なパッケージのみが環境に追加されます。「setup」をソースすると、オーバーレイとそれが作成されたアンダーレイをソースするため、両方のワークスペースを利用できます。
したがって、メインのROS2インストールを「setup」でソースし、次にオーバーレイ「ros2_ws/tutorials」の「local_setup」をソースすることと同じです。

これで、オーバーレイから「turtlesim」パッケージを実行できます。

しかし、これがオーバーレイ turtlesim の実行であり、メインのインストールの turtlesim ではないことをどうやって確認できるでしょうか?

オーバーレイで turtlesim に変更を行って確認してみます。

オーバーレイを変更する

オーバーレイを変更するには、TurtleSim ウィンドウのタイトル バーを編集します。これを行うには、「~/ros2_ws/tutorials/src/ros_tutorials/turtlesim/src」で「turtle_frame.cpp」ファイルを見つけます。

関数「setWindowTitle("TurtleSim");」を見つけて、値「"TurtleSim"」を「"MyTurtleSim"」に変更し、ファイルを保存します。

...

namespace turtlesim
{

TurtleFrame::TurtleFrame(rclcpp::Node::SharedPtr & node_handle, QWidget * parent, Qt::WindowFlags f)
: QFrame(parent, f)
  , path_image_(500, 500, QImage::Format_ARGB32)
  , path_painter_(&path_image_)
  , frame_count_(0)
  , id_counter_(0)
{
  setFixedSize(500, 500);
  setWindowTitle("MyTurtleSim");

  srand(time(NULL));

...
C++

先ほど実行した最初のターミナルに戻り、もう一度、「colcon build」を実行します。

2番目のターミナル(オーバーレイのソース)に戻り、turtlesim を再度実行します。

ウィンドウのタイトルが修正した「MyTurtleSim」に変わっています。

パッケージの作成

パッケージとは

パッケージは、ROS2コードのモジュール単位です。コードをインストールしたり、他の人と共有したりできるようにするには、パッケージに整理する必要があります。パッケージを使用すると、ROS 2 の作業をリリースし、他の人が簡単にビルドして使用できるようにすることができます。

ROS 2 でのパッケージ作成では、ビルド システムとして ament を使用し、ビルド ツールとして colcon を使用します。公式にサポートされている CMake または Python を使用してパッケージを作成できますが、他のビルド タイプも存在します。

パッケージの構成

ROS2 Python のパッケージの最低限必要なコンテンツは以下となります。

  • package.xml」… パッケージに関するメタ情報を含むファイル
  • resources/<package_name>」 … パッケージのマーカーファイル
  • setup.cfg」 … パッケージに実行ファイルがある場合に必要となる。「ros2 run」が、それらを見つけることができるようになる。
  • setup.py」 … パッケージのインストール方法の説明を含む
  • <package_name>」 … ROS2ツールがパッケージを見つけるために使用する。パッケージと同じ名前のディレクトリには、「__init__.py」が必要になる。

ROS2 CMake のパッケージの最低限必要なコンテンツは以下となります。

  • CMakeLists.txt」 … パッケージ内のコードを構築する方法を記述したファイル
  • include/<package_name>」 … パッケージの公開ヘッダーを含むディレクトリ
  • packege.xml」 … パッケージに関するメタ情報を含むファイル
  • src」 … パッケージのソースコードを含むディレクトリ

それぞれ、最も単純なパッケージファイル構造は次のようになります。

CMake用

Python用

ワークスペース内の3つのパッケージ

1 つのワークスペースには、それぞれ独自のフォルダーに、必要な数のパッケージを含めることができます。また、1 つのワークスペースに異なるビルド タイプのパッケージ (CMake、Python など) を含めることもできます。ネストされたパッケージを含めることはできません。

一般的なのは、ワークスペース内に「src」フォルダーを用意し、そこにパッケージを作成することです。これにより、ワークスペースの最上位レベルが「クリーン」に保たれます。

簡単なワークスペースは次のようになります。

パッケージを作成する

まずは、ROS2 インストール(アンダーレイ)をソースします。
新しいワークスペース「~/ros2_ws/tutorial_ws」を作ります。

パッケージ作成コマンドを使用する前に、「src」フォルダー内にいることを確認します。

ROS 2 で新しいパッケージを作成するためのコマンド構文は次のとおりです。

<build_type> には、以下の値を設定します。

  • CMakeの場合:「ament_cmake
  • Pythonの場合:「ament_python

ここでは、オプションの引数「--node-name」と「--license」を使用します。
--node-name」オプションは、パッケージ内に単純な Hello World タイプの実行可能ファイルを作成し、「--license」オプションは、パッケージのライセンス情報を宣言します。

ターミナルに次のコマンドを入力します。

これでワークスペースの「src」ディレクトリ内に「my_cpp_package」という新しいフォルダが作成されます。
コマンドを実行するとターミナルから次のメッセージが返されます。

続けてPython用のパッケージも作成します。
ターミナルに次のコマンドを入力します。

コマンドを実行するとターミナルから次のメッセージが返されます。

パッケージをビルドする

ワークスペースにパッケージを配置すると、ワークスペース ルートで「colcon build」を実行することでパッケージをビルドします。

ワークスペースルートに戻って、パッケージをビルドします。

ワークスペースに多数のパッケージがある場合は、時間がかかることがあります。
ビルドするパッケージを選択して実行する場合は、次のコマンドを実行します。

セットアップファイルをソースする

新しいパッケージと実行可能ファイルを使用するには、まず、新しいターミナルを開き、「~/ros2_ws/tutorial_ws」へ移動して次のコマンドを実行します。
なお、メインのROS2 インストールはソースされている必要があります。

ワークスペースがパスに追加されたので、新しいパッケージの実行可能ファイルを使用できるようになります。

パッケージを使用する

パッケージ作成中に引数「--node-name」を使用して作成した実行可能ファイルを実行するには、次のコマンドを入力します。

端末に以下のメッセージが返されます:

続いてPython版も実行してみます。

端末に以下のメッセージが返されます:

パッケージの内容を確認する

~/ros2_ws/tutorial_ws/src/my_cpp_package」と「~/ros2_ws/tutorial_ws/src/my_py_package」の内部には、「ros2 pkg create」で自動的に生成されたファイルとフォルダが表示されます。

package.xml をカスタマイズする

パッケージを作成した後の返信メッセージで、フィールド「description」にメモ(TODO)が含まれていることに気付いたかもしれません。これは、パッケージの説明が、パッケージをリリースする場合は必須となるためです。フィールド「maintainer」も入力する必要がある場合があります。

~/ros2_ws/tutorial_ws/src/my_cpp_package」にある「package.xml」エディターを使用して開きます。

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>my_cpp_package</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="chikuma@todo.todo">chikuma</maintainer>
  <license>Apache-2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>
XML

python版の「package.xml」も確認してみます。

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>my_py_package</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="chikuma@todo.todo">chikuma</maintainer>
  <license>Apache-2.0</license>

  <test_depend>ament_copyright</test_depend>
  <test_depend>ament_flake8</test_depend>
  <test_depend>ament_pep257</test_depend>
  <test_depend>python3-pytest</test_depend>

  <export>
    <build_type>ament_python</build_type>
  </export>
</package>
XML

名前とメールアドレスが「maintainer」に自動的に入力されていない場合は、その行に入力します。次に、「description」の行を編集してパッケージの概要を入力します。

ライセンス タグの下に、「_depend」で終わるタグ名がいくつかあります。これは、「package.xml」が
他のパッケージへの依存関係をリストし、colcon が検索する場所です。 
my_package」はシンプルで依存関係はありませんが、今後のチュートリアルでこのスペースが利用されることがわかります。

追加)Python版:「setup.py」の編集

Python版は、「package.xml」と同様のフィールドが「setup.py」にもあるため、そちらもメンテナンスする必要があります。

from setuptools import find_packages, setup

package_name = 'my_py_package'

setup(
    name=package_name,
    version='0.0.0',
    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='chikuma',
    maintainer_email='chikuma@todo.todo',
    description='TODO: Package description',
    license='Apache-2.0',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'my_py_node = my_py_package.my_py_node:main'
        ],
    },
)
Python

この続きのチュートリアルも行いますが、ブログ記事はここまでとします。

以上です。

コメント

タイトルとURLをコピーしました