PR

ロボット制御 #12 ROS2を使ってみる(RasPi5編)
ROS2 Jazzy を Raspberry Pi 5 にもセットアップして、チュートリアル(CLI)をガッツリ学習した話

制御

WindowsにDockerを使ってROS2 Jazzyを入れましたが、本命はこちらです。
結局、他にも利用しているWindowsパソコンだとロボット制御専用にはできないので、実際のプロジェクトは、Raspberry Pi 5の方で進めることになります。ただ、Raspberry Pi は、DebianベースでUbuntuベースではないので、パッケージをそのままインストールという訳には、行きませんでした。

  1. ROS2 Jazzy をインストールする
    1. ロケールの設定
    2. 必要なリポジトリを有効にする
    3. 開発ツールをインストール
    4. ROS2のビルド
    5. 数日後に再実行したら colcon build は動かなくなりました
    6. 環境のセットアップ
    7. 例題を実行
  2. ROS2 を学ぶ
    1. 環境設定
    2. turtlesim を動かしてみる
      1. turtlesim の起動
      2. ノードの確認
      3. rqt を使ってみる
      4. リマップ してみる
    3. ノードを学ぶ
      1. turtlesim のノードの確認
      2. リマップしてみる
      3. ノード情報
    4. トピックを学ぶ
      1. rqt_graph を確認してみる
      2. トピックのリスト
      3. トピックの情報
      4. トピックのエコー
      5. インターフェースの表示
      6. トピックへのデータ配信
      7. トピックのデータ公開速度
    5. サービスを学ぶ
      1. サービスのリスト
      2. サービスの型
      3. サービスのリスト(型付き)
      4. サービスの情報
      5. サービスの検索
      6. インターフェースの表示
      7. サービスをコールしてみる
      8. サービスのエコー
    6. パラメータを学ぶ
      1. 準備
      2. パラメータのリスト
      3. パラメータの取得
      4. パラメータのセット
      5. パラメータのダンプ
      6. パラメータのロード
      7. ノード起動時にパラメータファイルをロードする
    7. アクションを学ぶ
      1. 準備
      2. アクションを使ってみる
      3. ノードの情報
      4. アクションのリスト
      5. アクションのリスト(型付き)
      6. アクションの型
      7. アクションの情報
      8. インターフェースの表示
      9. アクション目標の送信
    8. rqt_console をログの表示に使ってみる
      1. セットアップ
      2. rqt_console のメッセージ
      3. ログレベルについて
      4. デフォルトのログレベルを設定する
    9. ノードの起動方法
      1. 起動ファイルの実行
      2. Turtlesim ノードを制御する

ROS2 Jazzy をインストールする

以下のサイトを参考(というかほぼその通り)にさせて頂きました。

ロケールの設定

前回の設定でロケールは、ja_JP.UTF-8になっています。
ROS2は、en_US.UTF-8 が前提とのことで、ロケール設置を変更しておきます。

/etc/locale.gen を編集します。

以下の3つのロケールをコメントアウトして有効にします。

ロケールを生成し、更新します。

必要なリポジトリを有効にする

まずは、必要なパッケージをインストールします。

ROS2 GPG キーを追加します。

リポジトリに追加します。

開発ツールをインストール

以下のようにコマンドを実行してパッケージをインストールします。

ROS2のビルド

ROS2 Jazzy のコードを取得します。

rosdepを使って依存パッケージをインストールします。

ROS2 Jazzy をビルドします。3時間弱かかりました。

数日後に再実行したら colcon build は動かなくなりました

別のRaspberry Pi 5 にこの方法でインストールしようとしたらエラーになりました。
その時の対応は、以下のPython3モジュールをインストールして、再度、上記のコマンドを実行しました。

しかし、ビルドが全く通りません。エラー発生のたびに「–packages-skip」に加えて実行していますが、インストール完了に辿り着くことが出来ていません。インターネットで発展しているパッケージは、日々、更新されているのは分かっていますが、数日前に出来ていたことが、まともに動かなくなるのは、残念で仕方ありません。
ビルドエラーの解決は非常に苦痛です。これでは、Raspberry Pi でのROS2って安定利用できるソフトウェアなのか疑問に感じ始めました。…解決したら記事を改定します。

環境のセットアップ

ROS2を使用するときには、以下を実行する。

例題を実行

新しいターミナルを開いて以下のように talker を実行します。

別のターミナルで以下のように listener を実行します。

Ctrl+C で終了します
インストールは、これで完了です。

ROS2 を学ぶ

ここでは、チュートリアルを実践してみます。
初心者用チュートリアル(CLI)を行って、ROS2の使い方を学習します。

環境設定

Raspberry Pi でROS2の演習をする際には、沢山のターミナルを立ち上げる事になります。
毎回、立ち上げるたびにセットアップをするのは面倒なので、ターミナル起動時に自動でセットアップが動くようにします。

上記のように一度セットアップしておけば、以降は、このおまじないは不要になります。

turtlesim を動かしてみる

turtlesim の起動

turtlesim は、ROS2 を学習するための軽量シミュレータです。
なのでチュートリアルでは、turtlesim を使ってROS2の基本を学習します。

まずは、パッケージがインストールされていることを確認します。

以下のように表示されれば、OKです。

基本的にROS2でプログラムを動かすときのコマンドはros2で始まります。
なのでどういったコマンドがあるかの調査は、以下で行います。

いずれも重要なコマンドですが、特に覚えておくべきものを確認しておきます。

runパッケージを実行する。
nodeノード関連の各種サブコマンド
topicさまざまなトピック関連のサブコマンド
service各種サービス関連のサブコマンド

この説明では、内容まではあまり分かりませんが、以下のROS2で何かを動かす場合には、以下の法則で動かすというルールがあることは分かりました。

では、turtlesim を動かしてみます。
動かす場合は、以下のコマンドで動かします。

turtlesimの受信側(サブスクライバー)は、以下のコマンドで動かします。

シミュレーターウィンドウが表示され、中央にランダムなカメが表示されます。
実行ファイル名「turtlesim_node」は、プログラムで決められている名前なので、この通りに指定しないと起動しません。

起動したターミナルに上記のように表示されて、別途、シミュレーション画面が表示されて中央にカメが配置されます。

turtlesim の発信側(パブリッシャー)は、以下のコマンドで起動します。

実行すると以下のように表示されます。

矢印キー(↑:前進、↓:後退、←:反時計回りに回転、⇒:時計回りに回転)や指定されたキー入力(G,B,V,C,D,E,R,T)に従って画面の上のカメが移動します。カメを止めるには[F]キー、プログラムを終了するには[Q]キーを入力します。
移動した軌跡は白い線となってシミュレータ画面に表示されます。

これで、受信側(サブスクライバー)と発信側(パブリッシャー)のノードが立ち上がりました。
この2つがメッセージを送受信してカメが動いています。

ノードの確認

ROS2におけるノードはモータを動かしたり、画像をカメラから入力して処理したりといった機能を担っています。各ノードは、トピック、サービス、アクション、パラメータを利用してほかのノードとデータを送受信します。ROS2では1つの実行ファイルに1つ以上のノードを含めることが可能です。
それでは、現在のノードがどうなっているか確認してみます。

上記のコマンドでノードリストを表示します。

以下のコマンドでノードの詳細情報を表示します。

ノード「/turtlesim」の詳細情報が表示されます。

ノード「/teleop_turtle」の詳細情報も表示してみます。

以下のように表示されます。

ノードが2つ立ち上がり、それぞれパブリッシャー(発信者)とサブスクライバー(受信者)として動いていることが分かります。2つのターミナルの送受信は、/turtle1/cmd_velを介して行われています。

この「/turtle1/cmd_vel」はトピックと呼ばれ、各ノードの通信の仲介をします。

rqt を使ってみる

まだ、rqtが入っていない場合は、以下で使ってインストールします。

新しいターミナルでrqtを起動します。

rqt が起動したら メニューから「plugins」→「Services」→「Service Caller」を選択します。

Service のプルダウンを選択すると沢山の呼び出し可能なサービスが表示されています。
先ほどのノード情報を確認したときに表示されていたサービスの情報が表示されています。

rqt から実際にサービスを呼び出すことが可能です。
サービスに「/spawn」を選択して、各パラメータを設定して呼び出してみます。

各パラメータを{x: 1.0, y: 1.0, theta: 0.0, name: ‘turtle2’}にしてCallしてみます。

カメが1匹追加されました。

別のサービス「/turtle1/set_pen」を呼び出してみます。
これは、turtle1の奇跡のペンの色やサイズを変更するサービスです。

ペンを変更後にカメを動かしてみます。

追加されたカメは動かないですね。

リマップ してみる

追加されたカメ(turtle2)を動かすためには、turtle_teoeop_keyがもう一つ必要ですが、普通に起動するとturtle1とも繋がってしまいます。この動作を変更するには、トピック「cmd_vel」をリマップします。

独立して追加されたカメ(tertle2)も動かせるようになります。

ノードを学ぶ

turtlesim のノードの確認

再び、turtlesimを起動します。2つのターミナルでそれぞれ以下をコマンドを実行します。

ノードリストを確認してみます。

リマップしてみる

リマップして別のシミュレーターを起動します。

新しいシミュレータ画面が表示されました。
ノードリストを確認してみます。

ノード情報

ノードの詳細情報を確認してみます。

カメを動かしてみます。「turtle_teleop_key」を動かしたターミナルで矢印キーを動かしてカメを動かしてみます。

1つの入力で2つのシミュレーターが同時に動くのが確認できました。

トピックを学ぶ

いつものように2つのターミナルで「ros2 run turtlesim turtlesim_node」と「ros2 run turtlesim turtle_teleop_key」を起動しておきます。
別のターミナルで「rqt_graph」コマンドを入力すると、rqt_graphのGUI画面が新たに立ち上がります。

rqt_graph を確認してみる

Node Graph の対象を「Nodes/Topics (active)」にして、Groupを0に、Debugのチェックをオン、tfのチェックをオンにすると以下のような表示になります。
最新化は、画面サイズに合わせてグラフを調整するのはで行うことが出来ます。

上記のノードとトピック、およびグラフの周囲にある 2 つのアクションが表示されます (今は無視します)。中央のトピック「/turtle1/cmd_vel」の上にマウスを移動すると、上の画像のように色が強調表示されます。

グラフは、/turtlesim ノードと /teleop_turtle ノードが /turtle1/cmd_vel トピックを介して相互に通信している様子表しています。/teleop_turtle ノードはトピックにデータ (カメを移動するために入力したキーストローク) を公開し、/turtlesim ノードはそのトピックをサブスクライブしてデータを受信します。

トピックのリスト

新しいターミナルで「ros2 topic list」コマンドを実行すると、システムで現在アクティブなすべてのトピックのリストが返されます。

「ros2 topic list -t」コマンドを実行すると、同じトピックのリストを返しますが、今回はトピックの種類が括弧内に追加されます。

これらの属性、特にタイプは、トピック間を移動するときにノードが同じ情報について話していることを認識する方法です。
これらすべてのトピックが rqt_graph のどこにあるか分からない場合は、[非表示] の下のボックスをすべてチェック解除できます。

トピックの情報

トピックの情報を表示するには、以下を使用します。

トピック /turtle1/cmd_dev の情報を表示します。

以下のように表示されます。

トピック /turtle1/cmd_vel が仲介するメッセージの型が「geometry_msgs/msg/Twist」であるということが分かります。このトピックを介してデータのやり取りを行っているパブリッシャーが1、サブスクライバーが1であることが分かります。

トピックのエコー

トピックに公開されているデータを表示するには、以下を使用します。

/teleop_turtle がトピック /turtle1/cmd_vel にデータを公開することがわかっているので、echo を使用してそのトピックを確認してみます。

最初、このコマンドはデータを返しません。これは、「/teleop_turtle」が何か公開するのを待機しているためです。

「turtle_teleop_key」が実行中のターミナルに戻り、矢印を使用してタートルを動かします。同時に 「echo」が実行中のターミナルを見ると、移動するたびに位置データが公開されていることがわかります。

「/_ros2cli_397」は、先ほど実行したechoコマンドによって作成されたノードです。(番号は異なる場合があります)。これで、パブリッシャーがトピックを介してデータを公開し、2 つのサブスクライバーがトピックにサブスクライブしていることがわかります。

インターフェースの表示

ノードはメッセージを使用してトピックを介してデータを送信します。パブリッシャーとサブスクライバーは通信するために同じタイプのメッセージを送受信する必要があります。

「ros2 topic list -t」や「ros2 topic info /turtle1/cmd_vel」を実行後に確認したトピックのタイプから、各トピックで使用されるメッセージの型が分かります。「cmd_vel」トピックの型は次のようになります。

これは、「geometry_msgs」中の「Twist」と呼ばれる「msg」が存在することを意味します。

「ros2 interface show <msg type>」を実行すれば、メッセージの型の詳細情報が確認できます。これは、トピックが仲介するメッセージのデータの構造です。

実行すると以下のように表示されます。

このメッセージの型が表しているのは、「linear」が直線移動の速さを表し、「angular」が回転の角度を表しています。
先ほどのトピックのエコーを確認するコマンドで確認してみると、上下の矢印キーではlinearのxの値がプラス/マイナスで表示され、左右の矢印キーではangularのzの値がプラス/マイナスで表示されます。

トピックへのデータ配信

メッセージ構造が確認できたので、次のコマンドを使用して、コマンド ラインから直接トピックにデータを公開できます。

引数'<args>'は、前のセクションで説明した構造でトピックに渡す実際のデータです。

この引数は YAML 構文で入力する必要があることに注意してください。完全なコマンドは次のように入力します。

「–once」 は、「メッセージを1つ公開して終了する」ことを意味するオプションです。

ターミナルに上記のように表示され、カメが少しだけ動きます。

カメを継続的に動作させるには、一定のコマンドストリームが必要です。
例えば、カメを動かし続けるにrは、次のコマンドを実行します。

先程とのコマンドの違いは、「–once」を「–rate 1」に置き換えています。これは、「メッセージを1Hzの周期で公開する」ことを意味するオプションです。

rqt_graph を更新すると、何が起こっているかをグラフィカルに確認できます。
ノード(/_ros2cli_4394)が /turtle1/cmd_vel トピックを介してメッセージを公開しており、それがノード(/turtlesim)とノード(/_ros2cli_4709)の両方で受信されていることが分かります。
なお、ノード(/_ros2cli_4709)は、「ros2 topic echo」コマンドを実行中のターミナルです。

さらに、/turtle1/pose トピックをエコーしてみます。

「/turtlesim」ノードが公開したメッセージを「/turtle1/pose」トピックを介して新しいノード「/_ros2cli_5055」がサブスクライブしていることが分かります。

トピックのデータ公開速度

次のコマンドを実行して、データが公開される速度を確認できます。

「/turtlesim」ノードが「/turtle1/pose」トピックにデータを公開している速度に関するデータを返します。

「/turtlesim」ノードの「/turtle1/pose」トピック公開速度は、「ros2 topic pub –rate 1 …」を実行して 1Hz(1秒間に1回)の間隔でメッセージを公開しているので、そのレートを反映した平均値が表示されます。

サービスを学ぶ

いつものように2つのターミナルで「ros2 run turtlesim turtlesim_node」と「ros2 run turtlesim turtle_teleop_key」を起動しておきます。

サービスのリスト

新しいターミナルで次のコマンドを実行すると、システムで現在アクティブな全てのサービスのリストが表示されます。

「teleop_turtle」と「turtlesim」の両方のノードに共通した7つのサービスが含まれていることが分かります。ROS2のほぼ全てのノードには、パラメータのベースとなるこれらのサービスがあります。

「/clear」についてはturtlesim固有のサービスなので、「/kill」に焦点を当てます。

サービスの型

サービスには、サービスの要求データと応答データがどのように構造化されるかを説明する型があります。サービス型はトピック型と同様に定義されますが、サービス型には要求用のメッセージと応答用のメッセージの 2 つの部分があります。

サービスの種類を確認するには、次のコマンドを使用します。

turtlesimの「/clear」サービスを見てみます。新しいターミナルで次のコマンドを入力します。

返される結果は次のとおりです。

この「Empty」タイプは、サービス呼び出しが要求を行うときにデータを送信せず、応答を受信するときにデータを受信しないことを意味します。

サービスのリスト(型付き)

すべてのアクティブなサービスのタイプを同時に表示するには、-t(--show-typesの省略)オプションをコマンドに追加します。

ターミナルに表示される結果:

サービスの情報

特定のサービスの情報を表示するには、次のコマンドを使用します。

このコマンドでは、サービスタイプとサービスクライアントおよびサーバーの数を返します。
例えば、「/cliear」サービスのクライアントとサーバーの数を調べることが出来ます。

ターミナルに表示される結果:

サービスの検索

特定のタイプのすべてのサービスを検索する場合は、次のコマンドを使用できます。

例えば、Empty 型の全てのサービスは、次のコマンドで見つけることが出来ます。

返される結果:

インターフェースの表示

コマンドラインからサービスを呼び出すことができますが、まず入力引数の構造を知っておく必要があります。

「/clear」サービスの型「Empty」でこれを試してください:

返される結果:

---は、リクエスト構造 (上) とレスポンス構造 (下) を分離します。ただし、前に説明したように、この
Empty型はデータを送受信しません。したがって、当然、その構造は空です。

「/spawn」のように、データを送受信する 型のサービスを調査してみます。
ros2 service list -t」の結果から、「/spawn」の型が であることが分かります。

「/spawn」サービスのリクエスト引数とレスポンス引数を確認するには、次のコマンドを実行します。

返される結果:

---行の上の情報は、「/spawn」を呼び出すために必要な引数を示し、x、y、thetaは、生成されたカメの 2D ポーズを決定しますが、nameは、明らかにオプションです。

この場合、—行の下の情報は知っておく必要はありませんが、呼び出しから取得する応答のデータ型を理解するのに役立ちます。

サービスをコールしてみる

サービス タイプとは何か、サービスのタイプの見つけ方、そのタイプの引数の構造を見つける方法がわかったので、次を使用してサービスを呼び出すことができます。

この<arguments>部分はオプションです。たとえば、Empty型指定されたサービスには引数がないことがわかります。

このコマンドは、タートルが描いた線を turtlesim ウィンドウから消去します。

次に、/spawn呼び出しと引数の設定によって新しいタートルを生成してみます。
<arguments>コマンドラインからのサービス呼び出しの入力は、YAML 構文である必要があります。

何が起こっているかについてのメソッド スタイルのビューと、サービスの応答が表示されます。

新しく生成されたカメがすぐに turtlesim ウィンドウに更新されます。

サービスのエコー

サービス クライアントとサービス サーバー間のデータ通信を確認するには、次のサービスを使用します。

「ros2 service echo」は、サービス クライアントとサーバーのサービス の内容に依存しますが、これはデフォルトでは無効になっています。これを有効にするには、ユーザーは、サーバー クライアントまたはサーバーを作成した後に「configure_introspection」を呼び出す必要があります。

別のターミナルを開き、以下を実行して、introspection_client および introspection_service のサービス を有効にします。

これで、introspection_clientintrospection_service の間のサービス通信を ros2 service echo 経由で確認できるようになりました。

これにより送信側、受信側のサービスの状態が確認できました。

パラメータを学ぶ

パラメータはノードの設定値です。パラメータはノード設定と考えることができます。ノードはパラメータを整数、浮動小数点数、ブール値、文字列、リストとして保存できます。ROS 2 では、各ノードが独自のパラメータを維持します。

準備

ここでもturtlesimパッケージを使用します。
いつものように2つのターミナルで/turtlesimと/teleop_turtleノードを起動します。

パラメータのリスト

ノードに属するパラメータを表示するには、新しいターミナルを開いて次のコマンドを入力します。

ノードの名前空間 /teleop_turtle と /turtlesim が表示され、その後、各ノードのパラメータが表示されます。

全てのノードには use_sim_time パラメータがありますが、これは turtlesim に固有のものではありません。
名前から判断すると、/turtlesim のパラメータには、RGBカラー値を使用して turtlesimウィンドウの背景色を決定するようです。

パラメータの型を決定するには、「ros2 param get」を使用します。

パラメータの取得

パラメータのタイプと現在の値を表示するには、次のコマンドを使用します。

「/turtlesim: background_g」パラメータの現在の値を確認してみます。

次の値が返されます。

これでパラメータ「background_g」の型は、整数で値は、「86」が設定されていることが分かります。
「background_r」「background_b」も確認してみると、「69」「255」が設定されていることが分かります。

パラメータのセット

実行時にパラメータの値を変更するには、次のコマンドを使用します。

端末から/turtlesimの背景色を変更してみます。

端末から次のメッセージが返されて、TurtleSimウィンドウの背景色が変わります。

「ros2 param set」コマンドでパラメータを設定すると、現在のセッションでのみ変更され、永続的に変更されるわけではありません。ただし、設定を保存して、次回ノードを起動するときに再読み込みすることができます。

パラメータのダンプ

次のコマンドを使用して、ノードの現在のパラメータ値をすべて表示できます。

このコマンドは、デフォルトでは標準出力(stdou)に出力しますが、パラメータ値をファイルにリダイレクトして後で使用できるように保存することも出来ます。「/turtlesim」のパラメータの現在の構成を「turtlesim.yaml」ファイルに保存するには、次のコマンドを入力します。

現在の作業ディレクトリに新しいファイルが出来ています。このファイルを開くと、次の内容が表示されます。

将来、同じパラメータでノードを再ロードする場合、パラメータをダンプしておくと便利です。

パラメータのロード

次のコマンドを使用して、ファイルから現在実行中のノードにパラメータをロードできます。

生成された「turtlesim.yaml」ファイルをノードのパラメータにロードするには、次のコマンドを入力します。

端末から次のメッセージが返されます。

読み取り専用パラメータは起動時にのみ変更でき、その後は変更できません。そのため、「qos_overrides」パラメータにはいくつかの警告が表示されます。

ノード起動時にパラメータファイルをロードする

保存したパラメータ値を使用して同じノードを起動するには、次を使用します。

これは、turtlesim を起動するために常に使用するコマンドと同じですが、--ros-args--params-fileが追加され、その後にロードするファイルが続きます。

実行中のturtlesim ノードを停止し、次のコマンドを使用して保存したパラメータで再ロードしてみます。

turtlesim ウィンドウは通常通り表示されますが、背景色は先ほど設定した紫色になります。

ノードの起動時にパラメータ ファイルを使用すると、読み取り専用のパラメータも含め、すべてのパラメータが更新されます。

アクションを学ぶ

アクションは ROS 2 の通信タイプの 1 つであり、長時間実行されるタスクを対象としています。アクションは、目標、フィードバック、結果の 3 つの部分で構成されます。

アクションはトピックとサービスに基づいて構築されます。アクションの機能はサービスと似ていますが、アクションはキャンセルできます。また、単一の応答を返すサービスとは異なり、アクションは安定したフィードバックを提供します。

アクションは、パブリッシャー/サブスクライバーモデルに似たクライアント/サーバーモデルを使用します。「アクションクライアント」ノードは、ゴールを「サクションサーバー」ノードに送信し、アクションサーバーはゴールを確認し、フィードバックのストリームと結果を返します。

準備

ここでもturtlesimパッケージを使用します。
いつものように2つのターミナルで「/turtlesim」と「/teleop_turtle」ノードを起動します。

アクションを使ってみる

/teleop_turtle ノードを起動すると、ターミナルに次のメッセージが表示されます。

アクションに対応する 2行目に注目します。(最初の命令は、トピックのチュートリアルで以前に説明した「cmd_vel」トピックに対応しています。)

G|B|V|C|D|E|R|T キーは、Fキーの周囲に「ボックス」を形成しています。(下写真参照)

各キーの位置は、turtlesimの方向に対応しています。例えば、「E」キーはタートルの方向を左上隅に回転させます。

「/turtlesim」ノードが動作しているターミナルを確認します。これらのキーのいずれかをおすたびに、「/turtlesim」ノードの一部であるアクションサーバーに目標が送信されます。目標は、タートルを特定の方向に回転させることです。タートルの回転が完了すると、目標の結果を中継するメッセージが表示されます。

「F」キーは、アクション実行中に目標をキャンセルします。

「C」キーを押してから、カメが回転を完了する前に「F」キーを押してみます。「/turtlesim」ノードが実行されているターミナルに、次のメッセージが表示されます。

クライアント側(/teleop_turtle)だけでなく、サーバー側(/turtlesim)でも目標を停止できます。サーバ側が目標の処理を停止することを選択した場合、目標を「中止」すると言われます。

「D」キーを押してから、目標までの回転が完了する前に「G」キーを押してみます。「/tertlesim」ノードが実行されているターミナルに、次のメッセージが表示されます。

このアクション サーバーは、新しい目標を取得したため、最初の目標を中止することを選択しました。新しい目標を拒否したり、最初の目標が完了した後に 2 番目の目標を実行したりするなど、他の選択も可能でした。すべてのアクション サーバーが、新しい目標を取得した際に現在の目標を中止することを選択するとは想定しないでください。

ノードの情報

この場合、「/turtlesim」ノードが提供するアクションのリストを表示するには新しいターミナルを開いて次のコマンドを実行します。

これにより、「/turtlesim」のサブスクライバー、パブリッシャー、サービス、アクションサーバー、およびアクションクライアントのリストが返されます。

ノード「/turtlesim」のアクション「/turtle1/rotate_absolute」が「Action Servers:」の下に表示されています。これは、「/turtlesim」が「/turtle1/rotate_absolute」に応答し、アクションに対するフィードバックを提供することを意味します。

ノード「/teleop_turtle」には、アクションが「Action Clients:」の下に表示されるはずです。
それを確認するには、次のコマンドを実行します。

以下の結果が返ってきます。

アクションのリスト

ROS グラフ内の全てのアクションを表示するには、次のコマンドを実行します。

返される結果:

これは現在 ROS グラフ内の唯一のアクションです。前に見たように、これはカメの回転を制御します。また、コマンドを使用することで、このアクションには、1つのアクションクライアント(/teleop_turtle の一部)と1つのアクションサーバー(/turtlesim の一部)があることも既に分かっています。

ROSグラフとは、ROSシステム内のノードのネットワークと、それらが通信するためのノード間の接続を指します。

アクションのリスト(型付き)

アクションには、トピックやサービスと同様にタイプがあります。「/turtle1/rotate_absolute」の対イプを確認するには、次のコマンドを実行します。

返される結果:

各アクション名の右側に括弧内(この場合は /turtle1/rotate_absoluteのみ)には、アクションの型(/turtlesim/action/RotateAbsolute)が表示されます。これは、コマンドラインまたはコードからアクションを実行するときに必要になります。

アクションの型

アクション型を確認する場合は、次のコマンドを実行します。

返される結果:

アクションの情報

次のコマンドを使用して、「/turtle1/rotate_absolute」アクションをさらに詳しく調べることができます。

返される結果:

これは、各ノードで「ros2 node info」の実行から以前に学んだことを示しています。「/teleop_turtle」ノードには、アクションクライアントがあり、「/turtlesim」ノードには、「/turtle1/rotate_absolute」アクション用のアクションサーバーがあります。

インターフェースの表示

アクション目標を自分で送信または実行する前に必要なもう1つの情報は、アクション型の構造でしす。

「ros2 action list -t」コマンドを実行したときに「/turtle1/rotate_absolute」の型を識別しました。ターミナルでアクションの型を指定して次のコマンドを入力します。

返される結果:

最初のセクションは目標リクエストの構造(データ型と名前)です。次のセクションは結果の構造です。最後のセクションはフィードバックの構造です。

ラジアン(radian)とは、角度を示す値です。
以下の式で角度[°]から角度[rad]に変換できます。
\(\displaystyle \theta [°] \times \frac{\pi}{180} = \theta [rad] \)
例えば、90°の場合は、以下の値になります。
\(\displaystyle 90[°] \times \frac{3.14}{180} = 1.57[rad] \)

アクション目標の送信

次のコマンドを使用して、コマンドラインからアクション目標を送信します。

カメが回転し、ターミナルに次のメッセージが表示されます。

全ての目標には、一意のIDがあり、返されるメッセージに表示されます。また、開始位置への変異を示す。「delta」という名前のフィールドの結果も確認できます。

この目標のフィードバックを表示するには、「ros2 action send_goal」コマンドに「–feedback」オプションを追加します。

端末から次のメッセージが返されます:

目標が達成されるまで、残りのラジアンのフィードバックを受け取り続けます。

rqt_console をログの表示に使ってみる

rqt_console」は、ROS 2 のログ メッセージを調査するために使用される GUI ツールです。通常、ログ メッセージはターミナルに表示されます。「rqt_console」を使用すると、時間の経過とともにそれらのメッセージを収集し、詳細かつ整理された方法で表示し、フィルター処理して保存し、保存したファイルを再ロードして別の時間に調査することもできます。

ノードは、ログを使用して、さまざまな方法でイベントやステータスに関するメッセージを出力します。その内容は通常、ユーザー向けの情報です。

セットアップ

今回は、「rqt_console」パッケージを使用します。
新しいターミナルを開いて「rqt_console」を起動します。

rqt_console」画面が開きます。

コンソールの最初のセクションには、システムからのログ メッセージが表示されます。

中央には、重大度レベルを除外してメッセージをフィルタリングするオプションがあります。右側のプラス記号ボタンを使用して、除外フィルターをさらに追加することもできます。

下のセクションは、入力した文字列を含むメッセージを強調表示するためのものです。このセクションにさらにフィルターを追加することもできます。

新しいターミナルを開いて「/turtlesim」ノードを起動します。

rqt_console のメッセージ

/turtlesim」ノードを起動すると、以下のように「Info」メッセージが2件表示されます。

rqt_console」に表示するログメッセージを生成するには、カメを壁にぶつけてみましょう。新しいターミナルで、以下のコマンドを入力します(トピックのチュートリアルで詳しく説明します)。

上記のコマンドはトピックを一定の速度で公開しているため、カメは継続的に壁にぶつかっています。
次のように、重大度レベルが「Warn」で表示された同じメッセージが何度も「rqt_console」に表示されます。

カメが壁にぶつかるのを止めるには、「ros2 topic pub」コマンドを実行したターミナルで「Ctrl+C」を押します。

ログレベルについて

ROS2 のログレベルは、重大度順に並べられています。

各レベルが何を示すかについての正確な基準はありませんが、次のように想定しても問題ありません。

  • 「Fatal」メッセージは、システムが損害から身を守るために終了しようとしていることを示します。
  • 「Error」メッセージは、必ずしもシステムに損害を与えるわけではないが、システムが正常に機能するのを妨げている重大な問題を示しています。
  • 「Warn」メッセージは、予期しない動き、または理想的でない結果を示します。これらは深刻な問題を示している可能性がありますが、機能に直接悪影響を与えるものではありません。
  • 「Info」メッセージは、システムが期待どおりに実行されていることを視覚的に確認するイベントとステータスの更新を示します。
  • 「Debug」メッセージは、システム実行のプロセス全体が段階的に詳細に示されます。

デフォルトのレベルは、「Info」です。デフォルトのレベルとそれよりも重大度の大きなレベルのメッセージのみが表示されます。

通常、「Info」より重大度が低いレベルは 「Debug」のメッセージのみであるため、「Debug」のみが非表示になります。たとえば、デフォルト レベルを「Warn」に設定すると、重大度が「Warn」「Error」「Fatal」のメッセージのみが表示されます。

デフォルトのログレベルを設定する

/turtlesim」ノードを起動するときに、デフォルトのロガー レベルを設定できます。
ターミナルで次のコマンドを入力します。

これで、前回「turtlesim」を起動したときにコンソールに表示された「Info」レベルのメッセージは表示されなくなります。これは、「Info」メッセージの優先度が新しいデフォルトの重大度「Warn」よりも低いためです。

ノードの起動方法

ほとんどの入門チュートリアルでは、実行する新しいノードごとに新しいターミナルを開いていました。同時に実行されるノードの数が増える複雑なシステムを作成すると、ターミナルを開いて構成の詳細を再入力するのは面倒になります。

起動ファイルを使用すると、ROS 2 ノードを含む複数の実行可能ファイルを同時に起動して構成できます。

ros2 launch」コマンドを使用して単一の起動ファイルを実行すると、システム全体 (すべてのノードとその構成) が一度に起動します。

起動ファイルの実行

新しいターミナルを開いて、以下を実行します。

このコマンドは、次の起動ファイル(コメントを削除)を実行します。

#!/usr/bin/env python3

from launch import LaunchDescription
import launch_ros.actions


def generate_launch_description():
    return LaunchDescription([
        launch_ros.actions.Node(
            namespace='turtlesim1', package='turtlesim',
            executable='turtlesim_node', output='screen'),
        launch_ros.actions.Node(
            namespace='turtlesim2', package='turtlesim',
            executable='turtlesim_node', output='screen'),
    ])
Python

この起動ファイルは、次の場所に保存されていました。
~/ros2_jazzy/install/turtlesim/share/turtlesim/launch/

上記の起動ファイルは Python で記述されていますが、XML と YAML を使用して起動ファイルを作成することもできます。これら様々な ROS2 起動形式の比較については、ROS2ドキュメントのハウツーガイドにある「ROS 2 起動ファイルに Python、XML、YAML を使用する」を参照してください。

これにより、2つの「/turtlesim」ノードが実行されます。

Turtlesim ノードを制御する

これらのノードが実行されているので、他の ROS 2 ノードと同じように制御できます。たとえば、2 つの追加のターミナルを開いて次のコマンドを実行すると、カメを反対方向に移動させることができます。

2番目のターミナル:

3番目のターミナル:

これらのコマンドを実行すると、次のような表示になります。

以上です。

コメント

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