概要

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

Arduino Nanoのピン配置
Arduino Nanoのピン配置
Arduino Nanoのピン配置です。公式ページ: https://content.arduino.cc/assets/Pinout-NANO_latest.pdf 備考 PWM出力が可能なピン:「~」が先頭についているピン...
Read More
Arduino Mega 2560 Rev3のピン配置
Arduino Mega 2560 Rev3のピン配置
Arduino Mega 2560 Rev3のピン配置です。公式ページ: https://content.arduino.cc/assets/Pinout-Mega2560rev3_latest.pdf 下部分の拡大 備考 上部...
Read More
Arduino Uno Rev3のピン配置
Arduino Uno Rev3のピン配置
Arduino Uno Rev3のピン配置です。 公式ページ: https://content.arduino.cc/assets/Pinout-UNOrev3_latest.pdf 備考 PWM出力が可能なピン:「~」が先頭につ...
Read More