拙著「ROS2とPythonで作って学ぶAIロボット入門」(講談社)を授業で使用する場合の講義資料のたたき台です.
今回は, [第2章 はじめてのROS2] の2.5節 ROS2プログラムの作り方を説明します.
1.レクチャ
内 容
- 次の節を教科書に従って説明する.スライドは作成中.
- 2.4 はじめてのROS2プログラミング
- 2.5 ROS2プログラムのつくり方
まとめ
1.1 ワークスペースの作成
-
- 概要
- これからROS2でいろいろなプログラムを作る.ROS2ではプログラムをパッケージ(package)とよばれる単位で作成する.まずは,パッケージを保存する作業用のディレクトリ(フォルダ)を作成する.ROS2ではこれをワークスペース(workspace)とよびます.1つのワークスペースに好きな数だけのパッケージを作ることができる.端末でパッケージを使うためには,設定ファイルを反映する必要がある.
- はじめに、ROS2システムの設定ファイルを反映する.これから新規に作成するワークスペースのパッケージをビルドするために必要.このROSシステムの環境のことをアンダーレイ(underlay),これから新規に作成するワークスペースの環境をオーバーレイ(overlay)とよぶ.オーバーレイはアンダーレイをもとにした環境.
- 設定ファイルの実行
- 次のsourceコマンドでアンダーレイの設定ファイル/opt/ros/foxy/setpu.bashを実行する.sourceはファイルに書かれたコマンドを現在のシェルで実行するコマンド.
$ source /opt/ros/foxy/setup.bash
- 次のsourceコマンドでアンダーレイの設定ファイル/opt/ros/foxy/setpu.bashを実行する.sourceはファイルに書かれたコマンドを現在のシェルで実行するコマンド.
- ワークスペース用ディレクトリの作成
- 次のコマンドでワークスペースに使用するディレクトリ
workspace_name
を作成する.ディレクトリ名は何でもよいがcolcon_ws
などが良く使われる.教科書のDockerイメージにはairobot_ws
が予め作成されている.演習用にはhappy_ws
を使う.なお,先頭の$は入力を受け付けるコマンドプロンプトなので打つ必要はない.$ mkdir -p ~/workspace_name/src
- 次のコマンドでワークスペースに使用するディレクトリ
- 概要
1.2 パッケージの作成
-
- 概要
- パッケージはあなたが作成したROS2コードの入れ物と考えることもできる.パッケージを使うことにより,あなたのROS2コードを簡単に公開したり,ビルドできるようになる.
- 種類
- ROS2ではビルドシステムとしてamentを使い,ビルドするツールとしてcolconを使う.CMakeまたはPythonを使ってパッケージを作成する.CMakeはソフトウェアをビルド,テストするツールでCやC++のビルドに使われる.
- 構成
- CMake:次のファイルが必須
- CMakeLists.txt:パッケージのコードをビルドする方法が書かれたファイル
- package.xml:パッケージに関するメタ情報が書かれたファイル
- Python
- setup.py:パッケージのインストールする方法が書かれたファイル
- setup.cfg:パッケージに実行可能ファイルがある場合に必要なファイル.ros2 runコマンドが実行可能ファイルを見つけるのに使う.
- package.xml:パッケージに関するメタ情報が書かれたファイル
- /package_nameパッケージと同じ名前のディレクトリ.ROS2のツールがパッケージに
__init__.py
があるかを見つけるのに使う.
- CMake:次のファイルが必須
- 作成
- ディレクトリを移動する.
$ cd ~/workspace_name/src
- 次のros2 pkg createコマンドで名前が
package_name
のパッケージを作成する.なお,package_name
の前後についている<と>はその引数(この場合はpackage_name)が省略できなことを示している. $ ros2 pkg create --build-type ament_python <package_name>
- なお,”
--node-name
“のオプションをつけるとノードも作成できる(オススメ).$ ros2 pkg create --build-type ament_python --node-name <node_name> <package_name>
- なお,”
- ディレクトリを移動する.
- 概要
1.3 ソースコードの作成
-
- ROS2のプログラムを作成する.典型的なROS2プログラムは次の処理をしている.
- 初期化
- rclpy.init(): ROS2通信のための初期化.ROS2ノード作成する前に呼び出さなければならない.
- ROS2ノードの作成
- 次のどちらかの方法で作成する.通常は後者を選ぶ.
- rclpy.create_node()関数を呼び出す
- Nodeクラスからインスタンスを作成する
- 次のどちらかの方法で作成する.通常は後者を選ぶ.
- ノードの処理(コールバック関数を使う場合が多い)
- 次の関数でノードを処理を実行する.
- rclpy.spin():処理を実行して,ノードが終了するまでブロックする.
- rclpy.spin_once():処理を1回実行するか,タイムアウトの期限までウェイトする.
- 次の関数でノードを処理を実行する.
- 終了処理
- rclpy.destroy_node():ノードを破壊する.
- rclpy.shutdown():終了処理をする.
- なお、簡単に説明した初期化や終了処理のAPIは以下のリンクで詳細がわかる.
- 初期化
- ROS2のプログラムを作成する.典型的なROS2プログラムは次の処理をしている.
1.4 ビルド
-
- ROS2ではビルドツールにcolconを使う.
- ビルドするためにworkspace_nameディレクトリに移動する.
$ cd ~/workspace_name
- 次のcolconコマンドでビルドする.このコマンドではワークスペースにある全てのパッケージをビルドする.
$ colcon build
- ビルドするためにworkspace_nameディレクトリに移動する.
- 便利なオプション
- packages-select:1つのパッケージmy_packageだけビルドしたいときはこのオプションをcolcon buildの後に付けてビルドする.
$ colcon build --packages-select my_package
- symlink-install:可能な場合,ファイルをコピーする代わりにシンボリックリンク(Windowsのショートカット)でインストールする.Pythonの場合は、これによりソースコードを改変しても再ビルドが不要になるお勧めのオプション.
$ colcon build --symlink-install
- packages-select:1つのパッケージmy_packageだけビルドしたいときはこのオプションをcolcon buildの後に付けてビルドする.
- ワークスペースで初めてビルドすると~/workspace_nameディレクトリにbuild,install,logディレクトリが作成される.
- ROS2ではビルドツールにcolconを使う.
1.5 設定ファイルの実行
-
- アンダーレイ設定ファイルの実行
$ source /opt/ros/foxy/setup.bash
- オーバーレイ設定ファイルの反映.作成したワークスペースの設定ファイルを実行する.これにより,あなたのワークスペースがパスに追加されるので,パッケージの実行可能ファイルを使えるようになる.
$ source ~/workspace_name/install/setup.bash
- アンダーレイ設定ファイルの実行
1.6 ノードの実行
-
- 次のros2 runコマンドで,パッケージ名package_name,ノード名node_nameを実行する.
$ ros2 run <package_name> <node_name>
- 次のros2 runコマンドで,パッケージ名package_name,ノード名node_nameを実行する.
2.ハンズオン (内容はAIロボット入門とは少し異なります)
A. 一連の作業体験
では、ワークスペース作成からパッケージ作成と実行までの一連の流れを体験しょう!この例ではワークスペース名をhappy_ws、Pythonパッケージとしている.なお,自動生成されるソースコードは端末に”Hi from hello”と表示されるだけでROS2ノードを作成しているわけではない.
- ワークスペースの作成と移動
$ mkdir -p ~/happy_ws/src
$ cd ~/happy_ws/src
- アンダーレイ設定ファイルの実行
$ source /opt/ros/foxy/setup.bash
- パッケージとノードの作成.
--node_name
オプションをつけると”Hi from hello.”と端末に出力するソースコードが自動生成される.ここではノード名をhello_node、パッケージ名をhelloにする. - ビルド
- ビルドの際はワークスペースのトップディレクトリに移動しなければならない.そのディレクリに移動してcolcon buildコマンドでビルドする.
$ cd ~/happy_ws
$ colcon build
- ビルドの際はワークスペースのトップディレクトリに移動しなければならない.そのディレクリに移動してcolcon buildコマンドでビルドする.
- オーバーレイ設定ファイルの実行
$ source install/setup.bash
- ノードの実行
- 自動生成されたソースコードの確認
- 少しハッピーになる設定
- 毎回、アンダーレイとオーバーレイの設定ファイルを実行するのは面倒なので次のコマンドを実行して.bashrcに追記する.
$ echo "source /opt/ros/foxy/setup.bash" >> ~/.bashrc
$ echo "source ${HOME}/happy_ws/install/local_setup.bash" >> ~/.bashrc
- 毎回、アンダーレイとオーバーレイの設定ファイルを実行するのは面倒なので次のコマンドを実行して.bashrcに追記する.
B. 初めてのROS2プログラム作成
次に、上で自動作成されたhello_node.pyを改変して初めてのROS2ノードのプログラムを作って行こう!
- エディタVSCodiumの起動
- 端末で次のコマンドを実行する.codiumコマンドの後の.(ドット)は現在のディレクトリのことで,この場合はhappy_ws.VSCodiumはこのディレクトリを開くことになる.なお,一度起動したVSCodiumは全作業が終わるまで使う.
$ cd ~/happy_ws
$ codium .
- 端末で次のコマンドを実行する.codiumコマンドの後の.(ドット)は現在のディレクトリのことで,この場合はhappy_ws.VSCodiumはこのディレクトリを開くことになる.なお,一度起動したVSCodiumは全作業が終わるまで使う.
- ソースコードの作成
- VSCodiumのエクスプローラーを使って,hello_node.pyを開く.上の作業で自動的に作成されたhello_node.pyは次図のようになっている。1行目のmain関数は端末に’Hi from hello.’を表示する.ここで5行目はこのコードをモジュールとしてimportできるようにするおまじない.詳しくはネットで調べてみよう!
- では,このhello_node.pyを次のコードで置き換えよう.コードにコメントがあるので,まず,それを読んでみよう.
- VSCodiumのエクスプローラーを使って,hello_node.pyを開く.上の作業で自動的に作成されたhello_node.pyは次図のようになっている。1行目のmain関数は端末に’Hi from hello.’を表示する.ここで5行目はこのコードをモジュールとしてimportできるようにするおまじない.詳しくはネットで調べてみよう!
import rclpy # 1. ROS2 Python モジュールのインポート from rclpy.node import Node # rclpy.node モジュールから Node クラスをインポート class HappyNode(Node): # HappyNodeクラス def __init__(self): print('ノードの生成') super().__init__('happy_node') # 基底クラスコンストラクタのよび出し self.get_logger().info('ハッピーワールド') # 4. ノードの処理 def main(): # main 関数 print('プログラム開始') rclpy.init() # 2. 初期化 node = HappyNode() # 3. ノードの生成 rclpy.shutdown() # 5. 終了処理 print('プログラム終了')
ソースコードの詳しい説明は,教科書P49 [2.5.2 はじめてのROS2プログラミング]を参照.
- Package.xmlファイルの編集
- 自動作成されたPackage.xmlを次に示す。ここで、変更する必要があるのは次の5項目。現時点では特に変更する必要はないが、自作パッケージを公開するときは変更しましょう。
- 4行目:name (パッケージ名)
- 5行目:version(パッケージのバージョン)
- 6行目:description (パッケージの説明)
- 7行目:maintainer email (保守者、メールアドレス)
- 8行目:license (パッケージのライセンス)
- 自動作成されたPackage.xmlを次に示す。ここで、変更する必要があるのは次の5項目。現時点では特に変更する必要はないが、自作パッケージを公開するときは変更しましょう。
- Setup.pyファイルの編集
- 自動作成されたSetup.pyを次に示す。ここで、変更する必要があるのは次の6項目。この内容は、Package.xmlと同じにしなければならない。パッケージを公開しない場合でも変更する必要がある項目は6番目のentry_pointsである。この例ではパッケージを作成するときに
--node-name
をつけてノードも作成したのでプログラムの開始点となるentry_points(エントリーポイント)も23行目のように自動的に生成されている。意味はhello_nodeのエントリーポイントはhelloパッケージのhello_nodeノードのmain関数となる。エントリーポイントが自動生成されると楽なのでパッケージを作成するときは--node-name
のオプションをつけよう!- 3行目:package_name (パッケージ名)
- 7行目:version(パッケージのバージョン)
- 16行目:maintainer (保守者)
- 17行目:maintainer_email (保守者のメールアドレス)
- 18行目:description (パッケージの説明)
- 23行目:entry points (プログラムの開始点)
- ‘ノード名 = パッケージ名.ノード名:main’
- 自動作成されたSetup.pyを次に示す。ここで、変更する必要があるのは次の6項目。この内容は、Package.xmlと同じにしなければならない。パッケージを公開しない場合でも変更する必要がある項目は6番目のentry_pointsである。この例ではパッケージを作成するときに
- ビルド
$ cd ~/happy_ws
$ colcon build
- オーバーレイ設定ファイルの実行
$ source ~/happy_ws/install/setup.bash
- ノードの実行
- 次のコマンドを実行して、下図のように表示されれば成功!
$ ros2 run hello hello_node
- 次のコマンドを実行して、下図のように表示されれば成功!
3.ホームワーク
- 教科書P49 [2.5.2 はじめてのROS2プログラミング] を読んで,チャレンジ2.4をやってみよう!
- 教科書P51 [2.5.3 コールバックを使ったプログラム] を読んで,チャレンジ2.5をやってみよう!
- 教科書P53 [2.5.4 例外処理を使った美しく終了するプログラム] を読んで,チャレンジ2.6をやってみよう!
終わり
参考リンク
コメント