#1.はじめに
ROS2を活用するには、Ubuntu 18.041を使用するのが一番手っ取り早いです。
(標準サポートがUbuntu・MacOS・Windows、パッケージは64bit対応だけ・・・)
丁度、Ubuntu公式からも、RaspberryPi向けUbubtu Linuxのイメージも提供されはじめたので、下手にROS2をRaspbianでコンパイルするよりも手軽かと思い、Raspberry Piの環境をUbuntuに完全移行してみました・・・が、やはりユーザが少なく情報も少ないので、特にGPIO周りの整備でハマりました。
ここでは、Raspberry Pi + Ubuntu 18.04 環境で、ROS2からGPIOを操作する際の考察と、最終的に、唯一まともに使うことが出来たWiringPiについて、コマンドライン版と、Python3版のインストールまでを概説します。
#2.GPIOライブラリの対応状況
Raspberry PiのGPIOを操作するには、いろいろなライブラリがありますが、Ubuntu + RaspberryPi環境で試したところいろいろ制約が見つかりました。
(評価環境)
Ubuntu 18.04.3 LTS (Bionic Beaver) arm64 版
http://cdimage.ubuntu.com/ubuntu/releases/18.04.3/release/
ライブラリ | 使える? | 問題(ハマったところ) |
---|---|---|
RPi.GPIO | × | pip等でインストール可能。puthonのスクリプトでimport時にエラー「This module can only be run on a Raspberry Pi!」が発生して使えない |
pigpio | △ | ソースからビルド可能。GPIO出力と、GPIO入力”エッジ”検出(立ち上がり・立ち下がりだけ)はOK。GPIO入力状態は検知不可(Readすると常に値が"0") |
WiringPi | × | ソースからビルド可能。"/proc/cpuinfo" ファイルの「Hardware」の項目が無くなったため、チップセットの情報が取得出来ず実行時にエラー「Oops: Unable to determine board revision from /proc/cpuinfo」が発生して使えない |
WiringPi + eoanパッチ | ○ | Ubuntu 19.10以降ではWiringPiパッケージが存在。上記の問題他を解決するパッチが提供されている |
##結論
19年9月時点では、
- Ubuntuのバージョン縛りがない場合
- Ubuntu 19.10 以降を使うと、WiringPiをパッケージでインストール可能。(動作確認済)
- (ROS2を使うなど)どうしてもUbuntu 18.04LTSを使いたい場合
- GPIO出力専用、あるいは、GPIO入力の”エッジ”だけ検出できれば良い場合は、pigpioを使う。
- WiringPi + eoanパッチをあてて、自力でコンパイルする。
(おまけ)JETSONでGPIOを使う場合
JETSONはUbuntu 18が動きます。
GPIOの操作に関しては、nvidiaが公式に Jetson.GPIO というライブラリを提供していますので、そちらを使います。
#3.インストール
Ubuntu 18.04で、WiringPiを使うためのビルド手順を解説します。
##(1) コマンドライン版のWiringPi
###準備
#作業ディレクトリを作成
$ mkdir ~/gitwork
$ cd ~/gitwork
#ソースのダウンロード
~/gitwork$ wget http://archive.ubuntu.com/ubuntu/pool/universe/w/wiringpi/wiringpi_2.50.orig.tar.gz
~/gitwork$ wget http://archive.ubuntu.com/ubuntu/pool/universe/w/wiringpi/wiringpi_2.50-0ubuntu1.debian.tar.xz
#展開
~/gitwork$ tar xzfv wiringpi_2.50.orig.tar.gz
~/gitwork$ tar Jxfv wiringpi_2.50-0ubuntu1.debian.tar.xz
###パッチを当てる
~/gitwork$ cd wiringpi-2.50/
#パッチのファイルを「wiringpi-2.50」ディレクトリにコピー
~/gitwork/wiringpi-2.50$ cp ../wiringpi_2.50-0ubuntu1.debian/patches/* ./
#パッチを当てる順番を確認
~/gitwork/wiringpi-2.50$ cat series
arm64-revision.patch
fix-dev-deps.patch
no-suid.patch
#パッチを当てる・その1
~/gitwork/wiringpi-2.50$ patch -u < arm64-revision.patch
can t find file to patch at input line 9
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|Author: Dave Jones <dave.jones@canonical.com>
|Description: Prefer /proc/device-tree for revision information
| All later kernels provide Pi revision information via /proc/device-tree. Use
| this in preference to /proc/cpuinfo, but retain fallback to the latter to
| continue support for older kernels.
|
|--- a/wiringPi/wiringPi.c
|+++ b/wiringPi/wiringPi.c
--------------------------
File to patch: wiringPi/wiringPi.c #### ← wiringPi/wiringPi.c をペースト
patching file wiringPi/wiringPi.c
#パッチを当てる・その2
~/gitwork/wiringpi-2.50$ patch -u < fix-dev-deps.patch
can t find file to patch at input line 12
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|Author: Dave Jones <dave.jones@canonical.com>
|Description: Fix various dependencies
| The libwiringPiDev library is missing a link dependency on libwiringPi. It
| also needs to include the path to the libwiringPi headers. The gpio utility
| has extraneous lib dependencies (librt, libm, and libcrypt). Finally, for
| libwiringPi itself, the libraries to link with must be placed at the end of
| the command line or the linker (with the now default -as-needed option) won t
| declare the exported nameds in the libraries as needed.
|
|--- a/gpio/Makefile
|+++ b/gpio/Makefile
--------------------------
File to patch: gpio/Makefile #### ← gpio/Makefile をペースト
patching file gpio/Makefile
can t find file to patch at input line 23
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|--- a/wiringPi/Makefile
|+++ b/wiringPi/Makefile
--------------------------
File to patch: wiringPi/Makefile #### ← wiringPi/Makefile をペースト
patching file wiringPi/Makefile
can t find file to patch at input line 35
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|--- a/devLib/Makefile
|+++ b/devLib/Makefile
--------------------------
File to patch: devLib/Makefile #### ← devLib/Makefile をペースト
patching file devLib/Makefile
ubuntu@raspi3u:~/gitwork/wiringpi-2.50$ patch -u <
COPYING.LESSER arm64-revision.patch examples/ pins/ wiringPiD/
INSTALL build fix-dev-deps.patch series
People debian/ gpio/ update
README.TXT debian-template/ newVersion version.h
VERSION devLib/ no-suid.patch wiringPi/
#パッチを当てる・その3
ubuntu@raspi3u:~/gitwork/wiringpi-2.50$ patch -u < no-suid.patch
can t find file to patch at input line 10
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|Author: Dave Jones <dave.jones@canonical.com>
|Description: Removed check for root on execution of gpio.
| The wiringPi library already has the ability to use the unprivileged
| /dev/gpiomem device if it can't open /dev/mem so there's no need to require
| root access for the gpio command, and hence no need to set the gpio command
| to have suid root privileges.
|
|--- a/gpio/gpio.c
|+++ b/gpio/gpio.c
--------------------------
File to patch: gpio/gpio.c #### ← gpio/gpio.c をペースト
patching file gpio/gpio.c
~/gitwork/wiringpi-2.50$
###ビルド
所々でワーニングが出ますが、特には問題無さそうです。
いつものようにporgを使って、簡易的なパッケージ管理をします。
#ビルド・インストール
~/gitwork/wiringpi-2.50$ sudo -lD ./build
#インストール確認
~/gitwork/wiringpi-2.50$ porg -a
wiringpi-2.50
~/gitwork/wiringpi-2.50$
###動作確認
見慣れた画面が出てきました。
~/gitwork/wiringpi-2.50$ gpio readall
+-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT5 | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | ALT5 | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | ALT0 | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | OUT | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 0 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+
~/gitwork/wiringpi-2.50$
##(2) Python3版のWiringPi
pip3でもインストールが可能ですが、一緒にWiringPiもコンパイルされるみたいで、先ほどのパッチがそのままでは当てることが出来ません。
そのため、githubからソースを入手して、WiringPiにパッチを当ててコンパイル・インストールする方法を使います。
###準備
#ビルドに必要なパッケージのインストール
$ sudo apt install python3-dev python3-setuptools swig
#作業ディレクトリを作成
$ mkdir ~/gitwork
$ cd ~/gitwork
#ソースのダウンロード
~/gitwork$ git clone --recursive https://github.com/WiringPi/WiringPi-Python.git
~/gitwork$ wget http://archive.ubuntu.com/ubuntu/pool/universe/w/wiringpi/wiringpi_2.50-0ubuntu1.debian.tar.xz
#パッチの展開
~/gitwork$ tar Jxfv wiringpi_2.50-0ubuntu1.debian.tar.xz
###パッチを当てる
~/gitwork$ cd WiringPi-Python/WiringPi/
#パッチのファイルを「WiringPi」ディレクトリにコピー
~/gitwork/WiringPi-Python/WiringPi$ cp ../../wiringpi_2.50-0ubuntu1.debian/patches/* ./
#パッチを当てる
~/gitwork/WiringPi-Python/WiringPi$ patch -u < arm64-revision.patch
can t find file to patch at input line 9
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|Author: Dave Jones <dave.jones@canonical.com>
|Description: Prefer /proc/device-tree for revision information
| All later kernels provide Pi revision information via /proc/device-tree. Use
| this in preference to /proc/cpuinfo, but retain fallback to the latter to
| continue support for older kernels.
|
|--- a/wiringPi/wiringPi.c
|+++ b/wiringPi/wiringPi.c
--------------------------
File to patch: wiringPi/wiringPi.c #### ← wiringPi/wiringPi.c をペースト
patching file wiringPi/wiringPi.c
Hunk #2 succeeded at 724 (offset -4 lines).
Hunk #3 succeeded at 742 (offset -4 lines).
Hunk #4 succeeded at 976 (offset -4 lines).
~/gitwork/WiringPi-Python/WiringPi$ patch -u < no-suid.patch
can t find file to patch at input line 10
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|Author: Dave Jones <dave.jones@canonical.com>
|Description: Removed check for root on execution of gpio.
| The wiringPi library already has the ability to use the unprivileged
| /dev/gpiomem device if it can't open /dev/mem so there's no need to require
| root access for the gpio command, and hence no need to set the gpio command
| to have suid root privileges.
|
|--- a/gpio/gpio.c
|+++ b/gpio/gpio.c
--------------------------
File to patch: gpio/gpio.c #### ← gpio/gpio.c をペースト
patching file gpio/gpio.c
###ビルド
所々でワーニングが出ますが、特には問題無さそうです。
~/gitwork/WiringPi-Python/WiringPi$ cd ..
~/gitwork/WiringPi-Python$ sudo python3 setup.py install
running install
running bdist_egg
running egg_info
creating wiringpi.egg-info
writing wiringpi.egg-info/PKG-INFO
(省略)
creating build/lib.linux-aarch64-3.6
aarch64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-aarch64-3.6/WiringPi/devLib/piFace.o build/temp.linux-aarch64-3.6/WiringPi/devLib/lcd128x64.o build/temp.linux-aarch64-3.6/WiringPi/devLib/scrollPhat.o build/temp.linux-aarch64-3.6/WiringPi/devLib/ds1302.o build/temp.linux-aarch64-3.6/WiringPi/devLib/lcd.o build/temp.linux-aarch64-3.6/WiringPi/devLib/gertboard.o build/temp.linux-aarch64-3.6/WiringPi/devLib/maxdetect.o build/temp.linux-aarch64-3.6/WiringPi/devLib/piGlow.o build/temp.linux-aarch64-3.6/WiringPi/devLib/piNes.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/mcp4802.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/mcp23017.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/pcf8591.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/mcp23016.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/wiringPiI2C.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/bmp180.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/drcNet.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/mcp23s17.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/mcp3422.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/drcSerial.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/softTone.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/ads1115.o build/temp.linux-aarch64-3.6/WiringPi/wiringPi/ds18b20.o build/temp.linu
~/gitwork/WiringPi-Python$
###動作確認
importしてみて、エラーが出なければ、ひとまずOK。
~/gitwork$ python3
Python 3.6.8 (default, Aug 20 2019, 17:12:48)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import wiringpi
>>>
:~/gitwork$
#4.参考資料
- https://wiki.ubuntu.com/ARM/RaspberryPi
- https://packages.ubuntu.com/eoan/wiringpi
- https://forum.qt.io/topic/101185/oops-unable-to-determine-board-revision-from-proc-cpuinfo
##ひとりごと
RaspberryPi対応のパッケージは、bionicくらいから、徐々に増えているようです。
eoanが出る頃に、概ね出揃う感じ?ですね。
ROS2ユーザ的には次のLTSである、Ubuntu 20.04が真打ちになりそうな気がします。
-
ネイティブで対応しているUbuntu MATEを使っても良いです(というのを、後で教えて頂きました^^;) ↩