ラズパイ3BのUbuntu20.04上にROS Noeticとラズパイマウスのドライバを導入した話

##はじめに
ROSのプログラミングをこれから学ぶにあたり、**RaspberryPiMouse V2**  [^1]（以下、ラズパイマウス）の中古品を譲っていただいたのですが、学習に着手する前に、**ubuntu 20.04** 上でのデバイスの設定作業が少し煩雑だったので、個人の忘備録を兼ねて手順を簡単に整理してみました。

この記事では、主に **Raspberry Pi 3B +** を使用していますが、設定が完了したSDカードを入れ替えた **Raspberry Pi 3B** でも動作することを実機で確認しました。
[^1]: 現在は、V2にパルスカウンタ機能等が追加された [Raspverry Pi Mouse V3](https://rt-net.jp/products/raspberrypimousev3/ '人工知能やロボットの学習に最適なロボット') が、本体だけ(Raspberry Pi無し)で60,000円（税別）で販売されている。V2は本体が5万円を切る値段だったところにさらに値上がりしている。普通に考えると、開発が進むにつれて機能を充実させて価格を据え置くか、さらに下げるというマーケティング戦略がとられる昨今で、かなり時代に逆行しているとも言え、将来的にこのデバイスが継続的に販売・提供されるのかは不確実とも思える。とはいえ、デバイスドライバはもちろん、デバイスの回路図まで公開されているので学習者にとっては楽しみが広がる。ソフトウェアをオープンソースがゆえにデバイス価格を上げざるを得ない（つまり、そこで利益を確保する）という現象に時代の難しさを感じる。

##作業目標
インストール作業にあたり、以下の要件を満たすことを目標としました。

* WiringPi でi2cを使った操作もできるようにする。[^2]
[^2]: [Raspberry Pi RGB Cooling HAT](https://www.yahboom.net/study/RGB_Cooling_HAT) が i2c 通信で OLED の表示をするので、すぐに i2c を使えるようにしたかった。同製品は、中国 Yahboom 社の製品で、同社のウェブサイトで$17.99で販売されているもの。

* WiringPi のC言語ライブラリも準備する。[^3]
[^3]: この Cooling HAT を使うには、WiringPi を使った温度管理プログラムのソースをビルドする必要があった。もともと Raspbian を使用する前提でデザインされているようで、Ubuntu18.04でうまくビルドができない旨をメールで同社のサポートセンターに送ったところ、すぐにメールの返信があり、スカイプで会話しながらサポートしてくれた。親切な対応だったが結局ビルドができず、teamviewerをPCにインストールしてSSHでラズパイに入って遠隔操作までしてくれたのだが、結局問題が解決せず、コンパイル済みの実行ファイルをメールで送ってくれた。こういうところは中国らしいというのか、同社のオープンな雰囲気を感じるが、セキュリティの観点でみるとサポート詐欺（サポートを提供しておいて、後で高額なサポート料を請求するというもの）というのもあって、今思えばちょっとリスクのある軽率な対応（もちろん自分が）だったと思う。これもまたオープンソースの世界で生きることの難しさだと思った。
* 「RaspberryPiで学ぶROSロボット入門」（上田隆一著）2017 日経BPに準拠する。[^4] 
[^4]: 大学の講義をそのまま本にしたような内容で、盛沢山。作業を時系列で説明するような構成になっている。自分のような初学者の学習用には向いているが、参考書のように後から調べる用途には使いにくい印象がある。2017年に出版された本で、python3にも対応していないので、これから勉強を始めるのに使う本としては、吉と出るか凶と出るか。評価の分かれるところだと思う。 
&nbsp;&nbsp;&nbsp;+ 本稿では、本書を「教科書」とよびます。

* Python はできればバージョン 2.7 対応[^5]
* ROSは、バージョン１を使用
* ラズパイマウスを卒業したら、ルンバの操作にもチャレンジしたい。（本稿とは無関係）


###1. Ubuntu 20.02のインストール
######OS選択- 心の叫び
ラズパイを正式にサポートしているOSは、以前はRaspbianだけでした。ハード面での性能向上にしたがって、とうとうUbuntuもその仲間入りをし、IoTがより身近になってきました。32ビット版と64ビット版があり、どちらを選択すべきか悩みましたが、メモリー容量を考えて、32ビット版を選択しました。

ラズパイ財団が64ビットを使うには1GMのメモリでは自ずと限界があると言っていたとubuntuが伝えています。

>
_The Raspberry Pi 2 only supports 32 bits, so that’s an easy choice. However the Raspberry Pi 3 and 4 are 64 bit boards. According to the Raspberry Pi foundation, there are limited benefits to using the 64 bit version for the Pi 3 due to the fact that it only supports 1GB of memory; however, with the Pi 4, the 64 bit version should be faster._
 - [Which image should I pick?](https://ubuntu.com/download/raspberry-pi)
>


######ラズパイにubuntuをインストールする方法 - 先人に感謝
OSのイメージファイルをダウンロードするubuntuのサイトにある[チュートリアル](https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi#1-overview "How to install Ubuntu on your Raspberry Pi")の説明も充分にわかりやすいのですが、[こちらの記事](https://qiita.com/myasu/items/5b122c782c5a616d8b60 "電子工作ファン向けのRaspberry Pi・セットアップ（Ubuntu 20.04LTS編）")にも手順が簡潔にまとめられていますので、インストールとその後の基本設定をするのに参考にしてください。

ログイン後のウェルカムメッセージは次のようになっていました。

```
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-1013-raspi armv7l)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sat Jul 11 14:16:16 JST 2020

  System load:           0.52
  Usage of /:            14.9% of 14.30GB
  Memory usage:          21%
  Swap usage:            0%
  Temperature:           44.5 C
  Processes:             128
  Users logged in:       1
  IPv4 address for eth0: 192.168.0.4
  IPv6 address for eth0: 240f:38:8327:1:ba27:ebff:fe37:f309


0 updates can be installed immediately.
0 of these updates are security updates.


Last login: Sat Jul 11 14:09:24 2020
ubuntu@ubuntu:~$
```

###2. i2cのインストール
こちらも、具体的には[前述の日本語記事](https://qiita.com/myasu/items/5b122c782c5a616d8b60 "電子工作ファン向けのRaspberry Pi・セットアップ（Ubuntu 20.04LTS編）")の該当部分を参照してください。

なお、ラズパイでi2cを利用可能にする方法は、raspi-config をインストールして行う方法もあります。Ubuntu 18.04までは、次のような方法でインストールできました。

```ruby:raspi-configの導入
$ sudo add-apt-repository ppa:ubuntu-pi-flavour-makers/ppa
$ sudo apt update
$ sudo apt instal
```

Ubuntu 19.10(eoan)を使っている場合は、`/etc/apt/sources.list.d/ubuntu-pi-flavour-makers-ubuntu-ppa-eoan.list`の修正が必要になるようです。具体的な修正方法は、[こちらの記事](https://askubuntu.com/questions/1130052/enable-i2c-on-raspberry-pi-ubuntu)に詳しいので参照してください。

###3. WiringPi のインストール
* [Raspbianライト・システムでのインストール方法](http://wiringpi.com/download-and-install/)とほぼ同じ

######あの呟きは何処へ
一番簡単なのは、正式なレポジトリからインストールする方法です。

```
$ sudo apt install wiringpi
$ gpio -v
gpio version: 2.50
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty
Raspberry Pi Details:
Type: Pi 3B+, Revision: 03, Memory: 1024MB, Maker: Sony
* Device tree is enabled.
*--> Raspberry Pi 3 Model B Plus Rev 1.3
* This Raspberry Pi supports user-level GPIO access. 
```

現在、`Raspberry pi 3B +` でレポジトリから `WiringPi` をインストールすると `version 2.50` になります。こちらは、[本家のサイト](http://wiringpi.com/download-and-install/)などからソースをダウンロードして使うこともできます。

```
$ cd /tmp
$ wget https://unicorn.drogon.net/wiringpi_2.50-0ubuntu1_armhf.deb
$ sudo dpkg -i wiringpi_2.50-0ubuntu1_armhf.deb

```
######WiringPiのライブラリの導入
このままでは、gcc を実行しても C プログラムが `wiringPi` のヘッダーファイルを見つけられない現象が生じます。しばらくの間（本当は膨大な時間）悩んだ末、「何かインストールするものが足りないんじゃないか」と気づきました。レポジトリを調べます。

``` 
$ sudo apt-cache search wiringPi
libwiringpi-dev - Raspberry Pi library for controlling GPIO devices
libwiringpi2 - Raspberry Pi library for controlling GPIO devices
wiringpi - Raspberry Pi tool for controlling GPIO devices
```

やっぱりありました。開発ライブラリ集。そこで、`libwiringpi-dev` をインストールします。

```
$ sudo apt install libwiringpi-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  libwiringpi-dev
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 9992 B of archives.
After this operation, 115 kB of additional disk space will be used.
Get:1 http://ports.ubuntu.com/ubuntu-ports focal/universe armhf libwiringpi-dev armhf 2.50-0ubuntu1 [9992 B]
Fetched 9992 B in 1s (13.0 kB/s)
Selecting previously unselected package libwiringpi-dev:armhf.
(Reading database ... 103795 files and directories currently installed.)
Preparing to unpack .../libwiringpi-dev_2.50-0ubuntu1_armhf.deb ...
Unpacking libwiringpi-dev:armhf (2.50-0ubuntu1) ...
Setting up libwiringpi-dev:armhf (2.50-0ubuntu1) ... 
``` 

これで、`gcc -o ... -lwiringPi` が無事に通るようになりました。

###4. ラズパイマウスのドライバのコンパイル 

######第一関門突破

まずは、[アールティのブログ](https://rt-net.jp/mobility/archives/12922)のとおり、デバイスドライバのREADMEに従ってやってみました。

```
$ cd ~
$ git clone https://github.com/rt-net/RaspberryPiMouse.git
Cloning into 'RaspberryPiMouse'...
remote: Enumerating objects: 572, done.
remote: Total 572 (delta 0), reused 0 (delta 0), pack-reused 572
Receiving objects: 100% (572/572), 3.64 MiB | 2.35 MiB/s, done.
Resolving deltas: 100% (215/215), done.
$ cd RaspberryPiMouse/
$ sudo apt install linux-headers-$(uname -r) build-essential
Reading package lists... Done
Building dependency tree
Reading state information... Done
linux-headers-5.4.0-1013-raspi is already the newest version (5.4.0-1013.13).
linux-headers-5.4.0-1013-raspi set to manually installed.
The following additional packages will be installed:
  dpkg-dev fakeroot libalgorithm-diff-perl libalgorithm-diff-xs-perl
  libalgorithm-merge-perl libfakeroot
Suggested packages:
  debian-keyring
The following NEW packages will be installed:
  build-essential dpkg-dev fakeroot libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libfakeroot
0 upgraded, 7 newly installed, 0 to remove and 0 not upgraded.
Need to get 836 kB of archives.
After this operation, 2646 kB of additional disk space will be used.
Do you want to continue? [Y/n] 
```

ここでYを押してインストールを完了し、ビルドコマンドに進みました。

```
$ cd utils/
$ ./build_install.bash
-bash: ./build_install.bash: No such file or directory
$ ls
RaspberryPiMouse  build_install.raspbian.bash  build_install.ubuntu14.bash
```

ファイル名を変更して再挑戦したところ、やっぱりエラーが出ます。

```
$ ./build_install.ubuntu14.bash
#!/bin/bash -vxe

dir=$(dirname $0)/../
++ dirname ./build_install.ubuntu14.bash
+ dir=./../
（中略）
/home/ubuntu/RaspberryPiMouse/src/drivers/rtmouse.c: In function ‘sw_read’:
/home/ubuntu/RaspberryPiMouse/src/drivers/rtmouse.c:547:5: error: implicit declaration of function ‘copy_to_user’; did you mean ‘raw_copy_to_user’? [-Werror=implicit-function-declaration]
547 |  if(copy_to_user((void *)buf, &sw_buf, count))
    |     ^~~~~~~~~~~~
    |     raw_copy_to_user
/home/ubuntu/RaspberryPiMouse/src/drivers/rtmouse.c: In function ‘led_write’:
/home/ubuntu/RaspberryPiMouse/src/drivers/rtmouse.c:825:6: error: implicit declaration of function ‘copy_from_user’; did you mean ‘raw_copy_from_user’? [-Werror=implicit-function-declaration]
825 |   if(copy_from_user(&cval, buf, sizeof(char)))
    |      ^~~~~~~~~~~~~~
    |      raw_copy_from_user                                                                                                                                         cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:275:
/home/ubuntu/RaspberryPiMouse/src/drivers/rtmouse.o] Error 1
make[1]: *** [Makefile:1734: /home/ubuntu/RaspberryPiMouse/src/drivers] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-1013-raspi'
make: *** [Makefile:7: rtmouse.ko] Error 2 
```

どうやら `copy_to_user` を`raw_copy_to_user`に、`copy_from_user` を `raw_copy_from_user` に変更する必要があるようです。コンパイラの指示に従ってエディタで作業します。

* 全体のソースコードは、[こちら](https://github.com/rt-net/RaspberryPiMouse/blob/master/src/drivers/rtmouse.c "RaspberryPiMouse/src/drivers/rtmouse.c")。

単純な書き換えなので、何も考えずに `vi` 。

```
$ vi ~/RaspberryPiMouse/src/drivers/rtmouse.c
```

* `copy_to_user` ==> `raw_copy_to_user` : 3カ所
* `copy_from_user` ==> `raw_copy_from_user` : 5カ所

修正したファイルを保存（esc/:/wq）して、`vi` を終了して、`make` します。 

```
$ make
```

エラーが出なければ良しとします。修正漏れがあると、修正不足の箇所を示してくれます。

```
$ pwd
/home/ubuntu/RaspberryPiMouse/src/drivers
$ ls
Makefile           Module.symvers  rtmouse.ko     rtmouse.mod.o
Makefile.raspbian  modules.order   rtmouse.mod    rtmouse.o
Makefile.ubuntu14  rtmouse.c       rtmouse.mod.c
$ sudo insmod rtmouse.ko
```

ちゃんと、`rtmouse.ko` ができているのを確認し、ドライバーをカーネルに組み込んで終了。/dev の下にrt... というファイルができているのを確認し、パーミッションを変更します。

```
$ ls -l /dev/rt*
crw------- 1 root root 510, 0 Jul 11 22:52 /dev/rtbuzzer0
crw------- 1 root root 511, 0 Jul 11 22:52 /dev/rtled0
crw------- 1 root root 511, 1 Jul 11 22:52 /dev/rtled1
（以下略）
$ sudo chmod 666 /dev/rt* 
```

######デバイスドライバのセットの自動化

* 後は、教科書（47ページ以下）の通りに、`crontab -e`で用意した `crontab.conf`をセットして `reboot` して作業完了です。万事正しければ「ピッ」と鳴ってドライバーがインストールされます。

・・・この音を聞くと、今回の苦労が報われた気持ちになりました。

###4. ROS Noetic のインストール
最後に、ROS 1 を導入します。Noetic は、ほんの数か月前にリリースされたばかりなので、ROS.Org の Installation 解説の手順でシンプルにインストールできました。

* [Ubuntu install of ROS Noetic](http://wiki.ros.org/noetic/Installation/Ubuntu)
[^5]: ROS Noetic は、Python 3 のみ対応だそうで、[こちらの記事](http://wiki.ros.org/noetic/Migration)にはっきりそう書いてあるのを発見した。 [Python 2 から 3 への移行ガイド](http://wiki.ros.org/UsingPython3)なるマテリアルも同サイトにおいてあったが、内容をざっと読んだ印象としては、とりあえずは手元のパッケージを python 3 でビルドしてみるしかないでしょう、みたいな感じです。まあ、そうなんでしょうね。
![IMG_20200712_113042_resized_20200712_113201252[665] - コピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663760/8aa3da08-63ae-f158-8b1e-0dab11d98a99.jpeg 'Raspberry Pi RGB Cooling HAT に搭載の OLED ディスプレーがお気に入り。')

###### 2020/07/12 初稿謝辞（英語ではDisclaimerともいうらしい。）
本稿は、ROSはもちろんC言語、Pythonといったプログラミング言語を少しだけかじったことがある程度で、電子工作や天体観測を週末の趣味とするアマチュア無線技士（3級）が投稿した記事です。したがって、エキスパート・ソフトウェアエンジニアの皆さんはもちろん、初学者の同胞の方から見ておかしな記載があるかもしれません。その場合は、ご指摘いただければ記事の修正などを真摯に検討いたします。また、内容の正確性や再現可能性についても間違いのない記載を努めておりますが、保証できるものではありませんのでご理解の上でご参照ください。