パッケージとノードの作成

ROS のパッケージとノードを作成します.

モチベーション

ROS の通信は, ノードと呼ばれる複数の実行可能ファイルが環境内で実行され, それらがさまざまな方法で相互に通信することが基本となっています. これらのノードはパッケージと呼ばれる構造内に存在します. 本演習では新たに作成したパッケージ内にノードを作成します.

Scan-N-Plan アプリケーション: 演習問題

これまでに ROS をインストールし, ワークスペースを作成し, さらにビルドを何回か行いました. ここでは自分たちが行いたいことをするために 独自のパッケージと独自のノードを作成します.

目標は ROS ノードを作成することです.

  1. まず catkin ワークスペース内に パッケージを作成する必要があります.
  2. 次にそこに独自のノードを記述します.

Scan-N-Plan アプリケーション: ガイダンス

パッケージの作成

  1. catkin ワークスペースの src ディレクトリに cd します.

    注: src ディレクトリ内に 全てのパッケージが作成されることを 憶えいておいてください.

    cd ~/catkin_ws/src
    
  2. ROS のコマンドを利用して roscpp に依存関係を有する myworkcell_core という パッケージを作成します.

    catkin create pkg myworkcell_core --catkin-deps roscpp
    

    ドキュメント catkin_tools を参照してこのコマンド理解を深めてください.

    • 本コマンドは新しいパッケージのための 新しいディレクトリと 必要なファイルを作成します.
    • 最初の引数は ROS パッケージの名前です.
    • --catkin-deps を用いて 新しいパッケージから依存関係にある パッケージを設定します.
  3. myworkcell_core という名前の フォルダができているはずです. そのフォルダに移動して package.xml ファイルを編集します. description や author など の記述を編集します.

    cd myworkcell_core
    gedit package.xml
    

    パッケージ作成時に 依存関係を追加することを忘れた場合は, 後から package.xml ファイルに 依存関係を追加することができます.

ストップ! この演習を続ける前にいくつかの講義スライドをもう一度見ていきます.

ノードの作成

  1. 本パッケージのフォルダで gedit を使用して CMakeLists.txt ファイルを編集します.

    例として書かれているルールを参考にしながら, 実行可能ファイル( add_executable )に vision_node という名前のノードと vision_node.cpp という名前の ソースファイルを追加します. また CMakeLists.txt 内で 新しく作成するノード vision_node が catkin ライブラリにリンクされている ( 'target_link_libraries' )こと を確認してください.

    add_compile_options(-std=c++11)
    add_executable(vision_node src/vision_node.cpp)
    target_link_libraries(vision_node ${catkin_LIBRARIES})
    

    これらの行は CMakeLists.txt の中の どこに記述されていても大丈夫ですが, 一般的には次のようにしています.

    • 上の add_compile_options の 既存のテンプレートのコメントを外します( project() の直下 )
    • 最下部近くにある add_executabletarget_link_libraries の 既存のテンプレートのコメントを外して編集します.
    • これにより,これらのルールが正しい指示で確実に定義され, 適切な構文を憶えやすくなります.

    注: テンプレートコードの target_link_libraries のように, ほとんどの CMakeLists ルールは 複数の行に分けて記述するできます.

  2. 本パッケージのフォルダで src/vision_node.cpp というファイルを作成します. ( gedit を利用 )

  3. ros のヘッダを加えます. ( ros.h のインクルード )

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
  4. main 関数を加えます. ( 典型的な C++ プログラム )

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
    
    }
    
  5. ROS ノードを初期化します. ( main 関数内 )

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
      // This must be called before anything else ROS-related
      ros::init(argc, argv, "vision_node");
    }
    
  6. ROS ノードハンドルを作成します.

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
      // This must be called before anything else ROS-related
      ros::init(argc, argv, "vision_node");
    
      // Create a ROS node handle
      ros::NodeHandle nh;
    }
    
  7. "Hello World" メッセージを ROS プリントツールを用いて表示します.

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
      // This must be called before anything else ROS-related
      ros::init(argc, argv, "vision_node");
    
      // Create a ROS node handle
      ros::NodeHandle nh;
    
      ROS_INFO("Hello, World!");
    }
    
  8. 自動的にプログラムから抜けないようにして, ノードが走っている状態を維持します.

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
      // This must be called before anything else ROS-related
      ros::init(argc, argv, "vision_node");
    
      // Create a ROS node handle
      ros::NodeHandle nh;
    
      ROS_INFO("Hello, World!");
    
      // Don't exit the program.
      ros::spin();
    }
    

    ROS_INFOlogging methods の1つです.

    • メッセージをターミナルに出力し, 他のノードから見られるように /rosout トピックに送信します.
    • DEBUG, INFO, WARNING, ERROR, FATAL の 5つのレベルのログがあります.
    • 他のログレベルを使用するには ROS_INFO または ROS_INFO_STREAM の INFO を適切なレベルに置き換えます.
    • printf 形式のログには ROS_INFO を使用し, cout 形式のログには ROS_INFO_STREAM を使用します.
  9. ターミナルのウィンドウで catkin build を実行して, プログラム(ノード)をビルドします.

    • catkin_ws(または任意のサブディレクトリ)の中から catkin build を実行しなければならないこと を忘れないでください.
    • myworkcell_core にあるプログラム, ライブラリなどをすべてビルドします.
    • 今回は1つの ROS ノード vision_node だけです.

ノードを実行する

  1. ターミナルを開いて ROS マスターを起動します.

    roscore
    

    ROS マスターは ROS ノードが働き始める前に 起動しておく必要があります.

  2. 2つ目のターミナルで 本演習のノードを実行します.

    • 前回の演習で .bashrc ファイルに追記して devel/setup.bash が新しいターミナルで 自動的に実行されるようにしました.

    • これによりビルドした結果が 新しいターミナルのセッションに自動的に反映されます.

    • 既に起動していたターミナルを利用する場合は, 新しいノードを追加した後に 手動でセットアップファイルを実行する必要があります.

      source ~/catkin_ws/devel/setup.bash
      
  3. ノードを実行します.

    rosrun myworkcell_core vision_node
    

    これは今作成したプログラムを実行します. 入力のスピードアップとエラーを減らすために Tab キーを使用することを忘れないでください.

  4. 3つ目のターミナルで どのようなノードが走っているのかを確認します.

    rosnode list
    

    /rosout ノードに加えて, 新しい /vision_node が リストされているはずです.

  5. rosnode kill /vision_node と入力してください.

    ノードが停止します.

    注: 現在のターミナルウィンドウで 実行中のノードを停止するには Ctrl+C を使用する方が一般的です.

チャレンジ

目標: あなたの名前を出力するようにノードを変更します. そのためにはビルドプロセスを再度実行する必要があります.