ROS2チュートリアル 体験記 (2/3)

著者:東風上奏絵

ROS2チュートリアル 体験記 (2/3)

チュートリアルの体験

それでは,早速チュートリアルを進めていきます.今回は,gbiggsさんが作成された,

ROS Japan ユーザグループ 講習会 ~ ROS 2 の紹介 ~ (https://gbiggs.github.io/rosjp_ros2_intro/index.html)

のチュートリアル資料を使わせていただきます.ROS2ならではのノードの書き方を理解し,ROS1との違いを探ることを目的とします.

インストール

Ubnutu 18.04にROS2 Bouncy をインストールします.ROS2 Bouncyのインストールはこちら (Desktop Install) を参照しました.ROS2のインストールがうまく行っているかはこちらで確認できました.

ROS2の基本

ROS 2の基本 に従ってチュートリアルを進めていきます.ROS1のチュートリアルでお馴染みの talker/ listener プログラム をROS2のノードの書き方で書いていくものです.

ROS2ならではのノードの書き方として,以下のポイントが挙げられると思います.

  • メインの関数の中ではなく,共有ライブラリとしてノードを実装する.(このようなノードをコンポーネントノードという.)コンポーネントノードとして実装することで,単体でも,ノードレットとして他のノードと組み合わせても使えるようになる.
  • そのために,他ソースファイルに利用するためのコンポーネントノードのクラス定義をまず行い(C++でいうところのhppファイル),その上で,コンポーネントノードの実装を行う(C++でいうところのcppファイル).

チュートリアルの詳細については,リンク先を参照していただきたいのですが,ここからは,チュートリアルを通して印象に残った点を挙げていきます.

実装時に印象に残った点

1. ROS2を利用するためにインクルードするヘッダの変更ROS2のノードの書き方を理解->コンポーネントノードのソースを読み解く->ヘッダーファイル 42行目):

#include <rclcpp/rclcpp.hpp>

ROS1におけるrospyrclpyに,roscpprclcppに変更になっています.

2. 初期化の方法の変更ROS2のノードの書き方を理解->コンポーネントノードのソースを読み解く->スタンドアローンノードラッパーのソースファイル 7, 8行目):

  rclcpp::init(argc, argv);
  auto greeter = std::make_shared();

ROS1では,

ros::init(argc, argv, "talker");

のようにROSの初期化に合わせてノードを初期化します.一方,ROS2では,ROSの初期化とノードの初期化が別々に分けられています.そのため,ノードを共有ライブラリとして実装すると,複数ノードを同一プロセスの中に入れられるようになります.

(詳しくはこちらのチュートリアルのmain関数4, 5行目

  rclcpp::init(argc, argv);
  auto node = rclcpp::Node::make_shared("greeter");

にも説明があります.)

すべてのノードはexecutorというオブジェクトの中で実行します.

こちらのチュートリアルgreet_and_displayer.cpp 10-18行目を抜粋します.

  // タイマーコールバック,トピックコールバック等を行うexecutor
  rclcpp::executors::SingleThreadedExecutor exec;

  // Greeterコンポーネントノードのインスタンスを作成しexecutorに登録する
  auto greeter = std::make_shared<greeter::Greeter>();
  exec.add_node(greeter);
  // Displayerコンポーネントノードのインスタンスを作成しexecutorに登録する
  auto displayer = std::make_shared<displayer::Displayer>();
  exec.add_node(displayer);

3. ノードなどのインスタンス作成時のスマートポインタの使用ROS2のAPIの基本を理解->ノードの実装 main関数5行目):

auto node = rclcpp::Node::make_shared("greeter");

ROS2はC++11/14を使っているため,autoを用い,変数のメッセージ型をコンパイラに判断してもらうようにします.コンパイラに型判断をお任せできるので,ソースコードが簡単になります.

4. ノードの制御の仕方の変更ROS2のノードの書き方を理解->コンポーネントノードのソースを読み解く->ソースファイル 19行目):

timer_ = create_wall_timer(1s, std::bind(&Greeter::broadcast_greeting, this));

ROS1の talker/ listener プログラム のチュートリアルでは,whileループを回し,一定時間ごとにsleepすることよってノードの周期を決めていました.ROS2では,リアルタイム制御や実行時間の管理のため,タイマーイベントで制御を行うことが推奨されています.

ビルド時に印象に残った点

1. ビルドシステムの変更ROS2のノードの書き方を理解->ビルド&実行):

ROS1ではcatkinを用いたビルドを行っていました.catkinは直接cmakeのみを扱います.一方,ROS2では,colconと呼ばれるメタビルドシステムを用います.colconは依存関係を考慮してパッケージのビルド順を決め,ビルドを実行します.ビルドの方法は各パッケージに任せるので,cmakeによらず複数のビルドタイプを選択可能です.

2. ソースコード実行のために実行ファイルのインストールが必須にROS2のAPIの基本を理解->パッケージのコンパイル方法 CMakeLists.txt 25-29行目):

# ノードの実行ファイルをインストールする(必須)
install(TARGETS
  greeter
  DESTINATION lib/${PROJECT_NAME}
  )

ROS1ではビルド時に,すべてのビルドされたファイルがソフトリンクされた,development space (devel space) が作られました.この開発環境を用いれば,インストールせずビルドのみで開発したソフトウェアを利用することができました.一方,ROS2のcolconビルドではdevel spaceが作られないため,開発パッケージのCMakeLists.txtに,実行ファイルのインストール先を指定する必要があります.(執筆者は,ROS1でdevel spaceを用いて自身が開発したソフトウェアを実行しており,正直に書くと,これまでインストールのことを意識していませんでした.)

colconについてはこちらのチュートリアルに詳しく紹介されています.

プログラム実行時に印象に残った点

1. source install/local_setup.bash を使用する端末で必ず一回実行ROS2のAPIの基本を理解->ビルド&実行):

source install/local_setup.bash

ROS1でいうところの source ~/catkin_ws/devel/setup.bash の代わりです.

2. 実行コマンドの変更 ( ros2 run greeter_ros2_style greeter )ROS2のAPIの基本を理解->ビルド&実行):

ros2 run greeter_ros2_style greeter
ros2 run displayer displayer

ROS1でいうところの rosrun greeter_ros1_style greeter の代わりです.その他のコマンドについてはこちらのチュートリアルに紹介されています.

3. roscoreが必要なくなるメッセージ受信ノードの作成->ビルド&実行):

データ通信方式が変更になりました.ROS1では,出版購読モデルの先駆けだったため,独自の出版購読モデルを構築していました.ROS2を開発する頃には,既存のライブラリが複数登場するようになりました.そのような経緯で,Data Distribution Service (DDS) を採用しました.これにより,マスタによるノード間接続が必要なくなり,DDSミドルウェアを介して直接ノード間で接続できるようになりました.ROSにおけるDDSは,こちらのサイトに詳しい説明があります.

その他,難しいなと思った点

執筆者が一番難しさを感じているのは,CMakeLists.txtの書き方です.これまでインストールのことを深く考えたことが無かったため,単にツケが回ってきただけだと思いますが,必要な情報についての理解がまだまだ足りていません.ヘッダーファイルのマクロの理解も追いついていません.ドキュメントを読んで,勉強していこうと思います.

さらに,これはROS1のチュートリアルを最初に勉強した時と同じ感想なのですが,talker/ listenerのプログラムの書き方が分かっても,自分が今使っているロボットをどのようにROS2で動かせば良いのかについてはまだよく分かりません.センサデータが取り扱えるパッケージなどの情報があると嬉しく思います.または,既存のROS1の認識系プログラム等をROS2用に置き換える方法が分かるとありがたいなと思いました.

また,ROS2のlaunchファイルは,xml形式からpython形式になったということです.まだ開発中ということで,これから情報が増えてくることを楽しみに待っています.

ROS2チュートリアル 体験記 (1/3)
ROS2チュートリアル体験記 (3/3)

著者について

東風上奏絵 contributor

コメントを投稿するにはログインしてください。