Note: This tutorial assumes that you have completed the previous tutorials: ja/rosserial_arduino/jaTutorials/Hello World.
(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Blink (example subscriber)

Description: This tutorial shows step by step how to use rosserial with subscribers.

Tutorial Level: BEGINNER

Next Tutorial: Using Time and TF

LEDの点滅: サブスクライバーを作る

コード

今はもうROSのパブリッシャーはprevious tutorialで作ったので、今度はサブスクライバーを作ってみましょう。もし、Arduino IDE Setup tutorialの通り行ってきたなら、ArduinoのIDEのメニューのros_lib->Blinkを選ぶことによって以下のスケッチを開けるはずです。

これで、以下のコードをIDEで開くはずです。

   1 /*
   2  * rosserial Subscriber Example
   3  * Blinks an LED on callback
   4  */
   5 
   6 #include <ros.h>
   7 #include <std_msgs/Empty.h>
   8 
   9 ros::NodeHandle nh;
  10 
  11 void messageCb( const std_msgs::Empty& toggle_msg){
  12   digitalWrite(13, HIGH-digitalRead(13));   // blink the led
  13 }
  14 
  15 ros::Subscriber<std_msgs::Empty> sub("toggle_led", &messageCb );
  16 
  17 void setup()
  18 {
  19   pinMode(13, OUTPUT);
  20   nh.initNode();
  21   nh.subscribe(sub);
  22 }
  23 
  24 void loop()
  25 {
  26   nh.spinOnce();
  27   delay(1);
  28 }

コード解説

では、コードを読み解いていきましょう。

   6 #include <ros.h>
   7 #include <std_msgs/Empty.h>
   8 

前にも行ったように、ros.hを他のROSのArduinoのプログラムと一緒にインクルードします。この場合、空のメッセージのためのヘッダーファイルもインクルードします。

   9 ros::NodeHandle nh;

次に、nodeハンドラをインスタンス化する必要があり、それによって、プログラムでパブリッシャーとサブスクライバーを作成できるようになります。nodeハンドラはシリアルポートの通信もサポートします。

  11 void messageCb( const std_msgs::Empty& toggle_msg){
  12   digitalWrite(13, HIGH-digitalRead(13));   // blink the led
  13 }

そしたら、サブスクライバーのためのコールバック関数を作ります。コールバック関数は引数に、コンスタントなメッセージへの参照を持ちます。このコールバック関数messageCbでは、メッセージのタイプはstd_msgs::Emptyでメッセージの名前toggle_msgです。

コールバックの中で、toggle_msgを参照できますが、空なので、する必要がありません。メッセージを受け取ったらArduinoのLEDが点滅するだけです。

  15 ros::Subscriber<std_msgs::Empty> sub("toggle_led", &messageCb );

この後使うパブリッシャーとサブスクライバーをインスタンス化する必要があります。ここでは、topicの名前が"toggle_led"でタイプがstd_msgs::Emptyであるサブスクライバーをインスタンス化しています。サブスクライバーとともに、メッセージを元にサブスクライバーを作ることを忘れてはいけません。(remember to template the subscriber upon the message)二つの引数はtopicがサブスクライブするものと、使うであろうコールバック関数です。

  17 void setup()
  18 {
  19   pinMode(13, OUTPUT);
  20   nh.initNode();
  21   nh.subscribe(sub);
  22 }

Arduinoのsetup関数では、ROSのnodeハンドラの初期化をし、サブスクライブをしたいまたはパブリッシュされるtopicの宣言をする必要があります。

  24 void loop()
  25 {
  26   nh.spinOnce();
  27   delay(1);
  28 }

最後に、loop関数で、ROSの通信コールバックを紐付けているros::spinOnce()関数を呼び出します。ros::spinOnce()はサブスクライブーのコールバック関数へメッセージを受け渡すのでloop関数の中で他にすることはありません。

コードを書き込む

Arduinoにコードを書き込むには、IDEの書き込み機能を使ってください。これは、他のスケッチを書き込むのと何も変わりません。

コードを実行する

さてroscoreを新しいターミナルで立ち上げてください。

roscore

次に、残りのROSにArduinoのメッセージを送り出すrosserialのクライアントアプリケーションを実行してください。正しいシリアルポートを使っているか確認してください。

rosrun rosserial_python serial_node.py /dev/ttyUSB0

最後に、rostopicを使ってLEDを切り替えることができます。

rostopic pub toggle_led std_msgs/Empty --once

さらに知りたい

パブリッシャーとサブスクライバーについてより詳しくはrosserial/Overviewをご覧ください。あわせてもっと複雑なデータのタイプの場合は limitationsをご覧ください。

Wiki: ja/rosserial_arduino/jaTutorials/Blink (last edited 2012-12-24 08:56:43 by Yuto Inagaki)