ラズパイにコントローラーを接続してデータをPCのROSで読み取る

　タイトルの通りです。コントローラーを利用してロボットを操作する場合，ノートPCごと持ち運ぶのはさすがに大変ですが，ラズパイならポケットに入るサイズなので便利ですよね。この記事ではラズパイにUbuntuをインストールするところから，PC上のROSでコントローラーのデータを読み取るところまでを説明しています。長いので適宜必要な部分を参考にしてください。
　UbuntuとROSはそれぞれUbuntu20.04とNoeticを使っていますが他のバージョンでも似たような感じでできるはずです。

# ラズパイ側の準備
　ラズパイにUbuntuを入れます。ここら辺のセットアップがすでに終わっている人は飛ばしてください。
## PCでの作業
　まずラズパイに使うmicroSDをPCに接続しましょう。
### Raspberry Pi Imagerでの作業
　[ここ](https://www.raspberrypi.com/software/)からUbuntu用のRaspberry Pi Imagerをダウンロードします。おそらくダウンロードしたdebファイルをダブルクリックすればインストールできると思います。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/c5d797cb-b0c3-664b-e2b7-48c9a647d657.png)
　起動できたら，
　`OSを選ぶ`→`Other general-purpose OS`→`Ubuntu`→`Ubuntu Server20.04.5 LTS(64-bit)`と順番に選択
　`ストレージを選ぶ`をクリックして，先ほど差し込んだmicroSDカードを選択
　`書き込む`をクリックしてmicroSDにUbuntuを書き込みます。
### GPartedでの作業
　次にターミナルを開いて
```
$ sudo apt install gparted
```
と入力して，GPartedをインストールします。ちなみにターミナルは`Ctrl`+`Alt`+`T`で開けます。
　GPartedを開いたら右上のメニューからmicroSDを選択します(間違ってPCのディスクを選択しないように！)。
　黄色のパーティションを右クリックして`リサイズ/移動(R)`を選択し，パーティションの右端を最大まで拡張します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/9bdbfa20-cb65-3304-33b8-e41d6884d8c1.png)
上の黄緑色のチェックをクリックして変更を適用しましょう。
 以上でPCでの作業は終わりです。

## ラズパイでの作業
　次にmicroSDをラズパイに差し込んで，ディスプレイとキーボードを繋いだら電源を供給して起動します。
　ラズパイの種類によってはHDMIからmicroHDMIへの変換アダプタ―などが必要なので事前に買っておいてください。
### ログイン
　Ubuntuが起動したら以下のように入力します。
```
ubuntu login: ubuntu
password: ubuntu
```
　すると初回起動時には
```
You are required to change your password immediately (administrator enforced)
Changing password for ubuntu.
Current password:
```
と表示されるので，`ubuntu`と入力してから好きなパスワードを設定してください。

### 50-cloud-init.yamlの編集
　次にラズパイがWiFiに接続できるようにします。
　ターミナルを開いて
```
$ sudo nano /media/$USER/writable/etc/netplan/50-cloud-init.yaml
```
と打ち込んでください。
```
network:
    ethernets:
        dhcp4: true
        optional: true
    version: 2
    wifis:
        wlan0:
            dhcp4: yes
            dhcp6: yes
            access-points:
                "WIFIのSSID":
                    password: "WIFIのPASSWORD"
```
　`wifis:`以降の部分を書き足しましょう。`"WIFIのSSID"`と`"WIFIのPASSWORD"`には接続したいWiFiのSSIDとパスワードを入れてください。このとき空白に`Tab`を使わないように注意してください。
　`Ctrl`+`S`で保存し，`Ctrl`+`X`でファイルを閉じます。
 
### キーボード設定
次にキーボード設定をします。特に必要ない人は飛ばしてください。
　今回は例として日本語キーボード，QWERTY配列を使っている人の設定方法を紹介します。
```
$ sudo dpkg-reconfigure keyboard-configuration
```
と打ち込んだら
`Generic 105-key PC (Intl.)`→`Japanese`→`Japanese`→`The default for the keyboard layout`→`No compose key`
と順番に選択します。結構時間が掛かるので待ちましょう。
　再起動して変更を適用します。
```
$ sudo reboot
```
### アップデート
　無事WiFiに接続することができたら，最初にアップデートの確認と更新を行います。
```
$ sudo apt update
$ sudo apt upgrade -y
```
 `-y`を付けると`yes/no`の選択で自動的に`yes`を選択してくれるようです。

　upgrade時に
```
Waiting for cache lock: Could not get lock /ver/lib/dpkg/lock-frontend. It is held by process xxxx (unattended-upgr)
```
と表示される場合は
```
$ sudo kill -9 xxxx
```
で解決する場合があります。また，普通に放置しても解決する場合があります。
### ネットワークの再設定
　次にネットワークの設定をします。
```
$ sudo apt install network-manager
$ nmtui
```
　紫色の画面が表示されたら
`Edit a connection`→`<Add>`→`Wi-Fi`と順に選択し，`Edit Connection`画面に適当な値を入力していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/567710fa-33fe-4437-933e-d931e064dfce.png)
　※画像は日本語化したUbuntuの物なのであまり参考にならないかもしれません。

　入力出来たら`<OK>`→`<Back>`→`Quit`と選択し，ターミナル画面に戻ります。
　次に先ほど変更した`50-cloud-init.yaml`の設定を元に戻します。
```
$ sudo nano /etc/netplan/50-cloud-init.yaml
```
 `wifi:`以降の記述を削除してください。できたら再起動します。
```
$ sudo reboot
```
　なぜこのような面倒臭い事をしているのかというと，`50-cloud-init.yaml`はあまり人の手で弄らない方が良いと[この記事](https://qiita.com/yas-nyan/items/9033fb1d1037dcf9dba5)に書いてあったからです。気になる人は読んでみてください。　
```
$ nmcli
```
と打ち込んでみると，先ほど設定したWiFiに接続できている事が確認できると思います。

### mDNSの指定

　次にmDNSを指定します。これはPCからラズパイにssh接続する際に，ipアドレスではなくデバイス名とユーザー名を用いる為の設定です。

　まずホストネーム(ubuntu@ubuntuの後ろの部分)を設定します。
```
$ sudo nano /etc/hostname
```
　`ubuntu`を削除して，好きなホスト名に書き換えてください。今回は`raspi01`とします。
　次にavahi-daemonを導入します。
```
$ sudo apt install avahi-daemon
$ sudo nano /etc/avahi/services/ssh.service
```
　以下のようにファイルを設定してください。
```xml
<pre>
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h
<service>
<type>_ssh._tcp</type>
<port>22
</service>
</service-group>
</pre>
```
```
$ sudo /etc/init.d/avahi-daemon restart
$ sudo /etc/init.d/avahi-daemon status
```
と打ち込んで，daemonが起動してそうなら大丈夫です。

　再起動します。
```
$ sudo reboot
```


### 新規ユーザーの追加
　以降の作業はssh接続によりPCからでも行うことができます。
　ラズパイと同一ネットワークに接続しているPCのターミナルに以下の文を打ち込んでみましょう。
```
$ ssh ubuntu@raspi01.local
```
　接続できましたか？　`raspi01`の部分は先ほど設定したホストネームに適宜変更してください。

　では新規ユーザーを追加していきます。今回は`slave01`とします。
```
$ sudo adduser slave01
```
　新しいパスワードの入力を求められるので適当に決めてください。その他の設定は`Enter`を押してスキップしても大丈夫です。最後にsudoでパスワードを入力しなくても良いように設定する。
ターミナルを開いて以下のコマンドを実行する。
```
sudo visudo
```
該当する部分に以下のような文を追加する。なお`ユーザー名`の部分は自分のユーザー名とすること。
```
# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL
ユーザー名 ALL=(ALL) NOPASSWD:ALL # 追加
```

　次に今追加したユーザーにsudo権限を付与して再起動します。
```
$ sudo gpasswd -a slave01 sudo
$ sudo reboot
```

# ROS関連の作業
## ROSのインストール
　新しいユーザーでログインしてみましょう。
```
$ ssh slave01@raspi01.local
```
　ログイン出来たら，ラズパイにROSnoeticをインストールします。
　[この記事](https://qiita.com/take4eng/items/70f167320ede46e4139c)が非常に分かりやすかったのでぜひ参考にしてください。ROSのインストールは非常に時間が掛かるので気長に待ちましょう。

　記事の通りにインストール出来たら`.bashrc`を変更します。
```
$ sudo nano ~/.bashrc
```
```
(省略)
source /opt/ros/noetic/setup.bash
source ~/catkin_ws/devel/setup.bash
export ROS_MASTER_URI=http://ROS-PC.local:11311
export ROS_HOSTNAME=$HOSTNAME.local
```
　最後の2行を追加してください。`ROS-PC`の部分はPCのホストネームにします。
```
$ source ~/.bashrc
```
　これによってPCで立ち上げたroscoreにラズパイのnodeが接続するようになります。
## joyのインストール
　コントローラーからデータを得るにはjoyという便利なパッケージを使います。
　ラズパイにインストールしましょう。
```
$ sudo apt update
$ sudo apt install ros-noetic-joy
```
　以上で準備は完了です。

# データを読み取ってみる
　とりあえずラズパイにコントローラーを接続します。今回筆者が使うのはLogicoolの[こちらの商品](https://www.amazon.co.jp/gp/product/B00CDG799E/ref=ppx_yo_dt_b_asin_title_o07_s00?ie=UTF8&psc=1)です。

　PC側でroscoreを立ち上げましょう。
```
$ roscore
```
　次にターミナルの別タブでラズパイにログインしてjoy_nodeを立ち上げます。
```
$ ssh slave01@raspi01.local
$ rosrun joy joy_node
```
　ターミナルの別タブでトピックを受信出来たら成功です！
```
$ rostopic echo /joy
```
![ros_joy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/7eedb44d-cfe3-30c8-153f-109145b2374c.png)
　コントローラーを動かしたときにトピックが更新されてこんな感じで表示されていたらうまくいっています（左側がPC，右側がラズパイで，左上が`roscore`，左下が`rostopic echo`）。ちなみにターミナルはTerminatorを使っています。
# 終わり
　今回はラズパイにコントローラーを接続してデータをPCのROSで読み取る方法について説明しました。受信したデータですが，接続する機器やコントローラーの機種によって形式が変わるようなので，実際に利用する際は色々試して対応を調べてみてください。