概要

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 <spi.h>
#include <ros.h>
#include <geometry_msgs/Twist.h>

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<geometry_msgs::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でエラーが出た場合は下記記事などを参考にしてください。

https://rb-station.com/blogs/article/rosserial-lost-sync-with-device-restarting

ArduinoRosRosserial

Related Posts

DCモータ制御で配線が複雑になる場合はDCモータコントローラシールドMD04を使うと便利!
DCモータ制御で配線が複雑になる場合はDCモータコントローラシールドMD04を使うと便利!
概要 DCモータを動作させる際は、モータコントローラを用いると便利ですが、それでも複数のモータを動作させようとしたときには配線がごちゃごちゃになってしまいがちです。そのような時は、シールドタイプのDCモータコントローラを使えば、マイコ...
Read More
Arduino Nano互換ボードで書き込めない時はプロセッサを確認
Arduino Nano互換ボードで書き込めない時はプロセッサを確認
概要 安価なArduino Nano互換ボードを使っていると、Arduino IDEで書き込みができずにエラーになってしまうことがあります。本記事ではその対処法について解説をします。 対処法 書き込み時にエラーが出る原因はさまざまな...
Read More
ブレッドボードに5V/3.3Vの電源をMB102で供給する
ブレッドボードに5V/3.3Vの電源をMB102で供給する
概要 ブレッドボードには電源を流すことに主に用いられる、両脇の赤と青のラインがあります。Arduinoなどのマイコンから5Vや3.3Vの電源を供給することもできますが、色々な用途に使っていると電流が足りなくなってしまったりするので、別...
Read More