概要

ROSを使って実機でロボット台車を動作させたい時に、Arduinoでシリアル通信経由でROSトピックを受信して、ロボット台車を動作させる方法を説明します。

/cmd_velは、平行移動の速度と回転速度が定義されたgeometry_msgs/Twistという型を用いた、ロボットの動作を指示するトピックです。

ROSがインストールされたデバイス(Jetson Nano等)とモータに繋がったArduinoをシリアルケーブルで繋いで、ROSの/cmd_velトピックをArduinoで受信する部分までの解説をします。Arduinoでモータを制御する方法については本記事では解説はしません。

接続

ROSが入ったマシンの設定

ROS側は、rosserialというパッケージを使います。シリアル通信を使ってROSトピックのやりとりができる非常に便利なパッケージです。

rosserialのパッケージをインストールします。(下記はmelodicの例)

sudo apt-get install ros-melodic-rosserial
sudo apt-get install ros-melodic-rosserial-arduino

続いて、Arduinoとシリアルケーブルで繋いだ後に、デバイスが表示されるかを確認します。大抵は、/dev/ttyACM0、/dev/ttyUSB0のような名前になることが多いです。

ls /dev/tty*

 などのコマンドで確認しましょう。

デバイスの確認 

続いて、Arduinoで使用するライブラリをこのマシンでビルドをします。公式チュートリアルも参考にしましょう。

※ Arduino IDEはインストールされている前提とします。

1つターミナルを立ち上げて、roscoreを起動します。

roscore

もう1つターミナルを立ち上げて下記を実行します。Arduinoのディレクトリ配下にあるlibrariesディレクトリに移動して、make_libraries.pyを実行します。

  cd sketchbook_path/libraries
  rm -rf ros_lib
  rosrun rosserial_arduino make_libraries.py .

 すると、librariesディレクトリ内にros_libディレクトリができると思いますので、Arduino IDEを再起動してExamplesの中にros_libがあれば準備が整った形となります。

尚、このros_libは別のマシンに移動しても使用することができるので、私はROSの入ったJetson Nanoでros_libディレクトリを作った後に、それをMacのlibrariesディレクトリに移してMacでも使っています。(MacだとROSが入れづらいので) 

Arduino側の設定

Arduino側のコード例は次のようになります。
#include 
#include 
#include 

ros::NodeHandle nh;

void messageCb(const geometry_msgs::Twist& twist) {
  // /cmd_vel受信後のコード
  int x = int( twist.linear.x * 100);
  char buf[100];
  sprintf(buf, "x = %d", x);
  nh.loginfo(buf);
}

ros::Subscriber<:twist> sub("cmd_vel", &messageCb);

void setup() {
  nh.getHardware()->setBaud(115200);
  nh.initNode();
  nh.subscribe(sub);
}

void loop() {
  nh.spinOnce();
  delay(1);
}

 

ros::Subscriber<geometry_msgs::Twist> sub("cmd_vel", &messageCb);

この部分で、cmd_velというトピックをsubscribeして、データを受信したらmessageCbがコールバック関数として呼ばれます。messageCbで受けた引数はgeometry_msgs::Twist型、つまり、下記のようなオブジェクトになります。

Vector3 linear
    float64 x
    float64 y
    float64 z
Vector3 angular
    float64 x
    float64 y
    float64 z

例えば、x方向の速度を取得したい場合は、 twist.linear.xのように取得できます。例ではtwist.linear.xを100倍した値を出力することだけをしています。

あとはこれらの値に応じてモーターを動作させるコードを追記すれば大丈夫です。今回はモーターを動作させる部分は省略します。

/cmd_velの送信

まず、ROSが入ったマシンとArduinoがケーブルで繋がれていることを確認してください。

ROSが入ったマシン側で1つターミナルを立ち上げてcmd_velを発行できるノードを立ち上げます。例ではturtlebot3のteleopパッケージを使用していますが、詳しいインストール方法は省略します。

roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch

もう1つのターミナルを立ち上げて、rosserialを実行します。 

rosrun rosserial_python serial_node.py /dev/ttyUSB0 _baud:=115200

 rosserial

送信した/cmd_velの値が、rosserialの方で出力されていれば正常にArduino側に値が送られていることになります。

rosserialのデバッグ方法については下記記事を参考にしてください。

 

ArduinoRosRosserial

Related Posts

Arduinoのrosserialで「Unable to sync with device」というエラーが出た場合の対処
Arduinoのrosserialで「Unable to sync with device」というエラーが出た場合の対処
概要 ArduinoでROSのトピックを受信して動作をさせたいときに、使うのがrosserialです。 rosserial_arduino このrosserial_arduinoを用いてArduinoと繋げてROSトピックを投げ...
Read More
Arduinoのコードでキュー(Queue)を使う
Arduinoのコードでキュー(Queue)を使う
概要 Arduinoのコードを書く際に、処理をキューイングして順番に処理をしていきたい時がありました。Arduinoにはarrayはありますが、FIFO(後述)型のキューはデフォルトでは無いため、外部ライブラリをインクルードする必要が...
Read More
2輪駆動 ロボット台車・カーシャーシの組み立て方
2輪駆動 ロボット台車・カーシャーシの組み立て方
RoboStationで販売しているロボット台車・「積載重量4kg/3kg 2輪駆動 ロボット台車・カーシャーシ」の組み立て方について解説をします。   RoboStation https://rb-station.com/prod...
Read More