LoginSignup
12
15

More than 1 year has passed since last update.

ROSによるArduinoの制御方法

Last updated at Posted at 2021-01-03

概要

ROS を用いた Arduino の制御方法や、その環境構築について解説していきます。
公式のページ:http://wiki.ros.org/rosserial_arduino/Tutorials/Arduino%20IDE%20Setup

説明すること

  • ROSでArduinoを制御するための環境構築方法
  • Arduinoに組み込むプログラムの内容

動作環境

  • Raspberry Pi 4 (4GB)
  • Ubuntu server 20.4LTS (64bit)
  • ROS Noetic
  • ELEGOO R3 UNO (Arduino互換ボード)

環境構築手順

  1. Arduino IDE のインストール
  2. 依存パッケージのインストール
  3. Arduinoライブラリのインストール
  4. 動作確認

1. Arduino IDE のインストール

1-1. インストール手順

  1. 下記サイトの『Linux ARM 64bits』から圧縮ファイルをダウンロード
    https://www.arduino.cc/en/software
  2. ダウンロードしたファイルをHOMEフォルダに展開
  3. 展開したフォルダ内の『install.sh』を実行
  4. デスクトップに『Arduino IDE』のアイコンが作成される

1-2. 動作確認

まずはROSを絡めずに、Arduinoが問題なく動作するかを確認する。
Untitled Sketch 2_ブレッドボード.png

  1. Arduinoの11番ピンでLEDが光るように配線 (上図)
  2. Raspberry Pi と Arduino を接続
  3. ツール ⇒ ボード で対象ボードを設定
  4. ツール ⇒ シリアルポート 対象ポートを設定
  5. Arduino IDE を起動し、下記ソースを記述
  6. コンパイルし、マイコンボードに書き込む
  7. LEDが点滅すればOK
void setup() {
  pinMode(11, OUTPUT);
}

void loop() {
    digitalWrite(11,HIGH);
    delay(100);
    digitalWrite(11,LOW);
    delay(100);
}

書き込み時にパーミッションエラーとなる場合、ユーザーを『dialout』グループに所属させる必要がある。

sudo usermod -a -G dialout <ユーザ名>

ここで動作しないなら、設定が間違っているかArduinoが壊れている。

2. ROS依存パッケージのインストール

ROS公式のページを見ると、インストール方法には2種類の方法がある。

  • apt によるインストール
  • ソースビルドによるインストール

本来は上記のどちらかでインストールできるはずだが、うまく動作しなかったため両方行った。

apt によるインストール

sudo apt install ros-noetic-rosserial-arduino
sudo apt install ros-noetic-rosserial

ソースビルドによるインストール

cd ~/catkin_ws/src
git clone https://github.com/ros-drivers/rosserial.git
cd ~/catkin_ws
catkin_make

※ 公式の方法でトラブル発生
上記のソースビルドの場合、公式では最後にcatkin_make installをしろと書いてある。
が、これを実行すると他パッケージのビルド関連が無効になってしまった。
catkin_make installは無くても動作するため、今回は省略している。

3. Arduinoライブラリのインストール

ライブラリ自体は『Arduino IDE』から取ってくる。(非公式?)

  1. Arduino IDE を起動
  2. スケッチ ⇒ ライブラリをインクルード ⇒ ライブラリを管理
  3. 『rosserial』と検索
  4. Michael Furguson 氏の『Rosserial Arduino Library』のバージョン0.7.9をインストール
  5. <ros.h> のインクルードが使用可能

参考ページ:https://answers.ros.org/question/361930/rosserial-arduino-compilation-error-no-cstring/

※ 公式の方法でエラー発生 (Noeticだけかも)
公式では下記方法でライブラリが作成されるが、本環境ではコンパイル時にエラーとなる。
もし上手くいかなかったら、『ros_lib』を削除し、上記の方法でやり直す。
参考までに。

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

上記コマンドにより『ros_lib』が生成される。

4. 動作確認

上記までで一通りの動作環境が整ったので、実際に動作するかの確認を行う。

実装内容:PC操作でROSから信号を受け取ったときにLチカする

4-1. Arduino にプログラムを組み込む

下記コードをArduino IDEに記述し、マイコンボードに書き込む。

#include <ros.h>
#include <std_msgs/Empty.h>

ros::NodeHandle nh;

void messageCb( const std_msgs::Empty& toggle_msg) {
  digitalWrite(11, HIGH);
  delay(100);
  digitalWrite(11, LOW);
  delay(100);
}

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

void setup(){
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH); 
  nh.initNode();
  nh.subscribe(sub);
}

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

4-2. ROSでの制御

ターミナルを3つ立ち上げ、それぞれ下記コマンドを実行。

1つ目:ROSマスターの起動

ターミナル1
roscore

2つ目:ROSシリアル通信の開始
最後の『/dev/ttyACM0』は各環境に合わせる。

ターミナル2
rosrun rosserial_python serial_node.py /dev/ttyACM0

3つ目:トピックを送信
コマンドを送信するたびにLEDが光る。

ターミナル3
rostopic pub toggle_led std_msgs/Empty --once

ここまで問題なく動作していればOK。
あとはArduinoに組み込むプログラムやROSのパブリッシャーを用意することで、自由に Arduino を制御することが可能となる。

Arduino内のサブスクライバー

Arduino に組み込むプログラムは、『ROSライクな記述ができる』だけであって、ROSとは記述方法が異なる。
が、だいたいは通常のパブリッシャー・サブスクライバーと同じように記述することになる。

上記で使用したコードを例に解説を行う。
PC内の ROS からトピックを受け取ってLチカするという事は、『Arduino内ではサブスクライバーが実行されている』と考えてもらいたい。

各コードの解説

ROSヘッダー、トピックの型のインクルード
ROSヘッダーは必須。
以降は使用するトピックに合わせて必要な分だけインクルードする。

#include <ros.h>
#include <std_msgs/Empty.h>

ROSノードハンドルの宣言
setup関数、loop関数の両方で使用するため、グローバル変数として宣言する。

ros::NodeHandle nh;

コールバック関数
トピックを受け取った時の動作内容をコールバック関数内に記載する。
普段 Arduino に記述している内容はここに書くことが多くなる。

void messageCb( const std_msgs::Empty& toggle_msg) {
  digitalWrite(11, HIGH);
  delay(100);
  digitalWrite(11, LOW);
  delay(100);
}

トピックとコールバック関数を紐付け
サブスクライバーに、上記で作成したコールバック関数とトピック名を紐付ける。
本家と異なり、サブスクライバー宣言時にトピックの型を指定する必要がある。
サブスクライブするトピックの名前や型を変更する場合、ここで指定する。

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

setpu関数 (初期化)
Arduino 起動時に一度だけ実行される関数。
通常の Arduino の初期化コードに加え、ノードハンドルの初期化、サブスクライバーの追加を行う必要がある。

void setup(){
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH); 
  nh.initNode();
  nh.subscribe(sub);
}

loop関数 (無限ループ)
Arduino 起動中に繰り返される関数。
基本的にはコールバック関数を実行するためのnh.spinOnce();を記述するだけで良い。

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

参考ページ

http://wiki.ros.org/rosserial_arduino/Tutorials
https://qiita.com/nnn112358/items/059487952eb3f9a5489b

12
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
15