ogochan
ROS2を動かすためには、事実上Ubuntu環境であることが必須です。
もちろんソースが公開されているので、他の環境でもやってやれないことはないのですが(やってみました)、エネルギーは大変なものです。いろんなツールをなるべくミニマムで揃えるのは、なかなか大変です。
VR徘徊のPoCで使うマイコンは、諸般の事情からStereo Pi Ver 1です。ところがこいつは開発が古いのと、新しいものが出てしまった関係でOSも情報も古いままで、「新しめのUbuntuをインストールしてカメラを動かす」ということも一苦労です。
原始的なことをしながら動かすことに成功したので、どれだけ需要があるかわかりませんがメモを書いておきます。
背景
VR徘徊のためには、ステレオカメラが必要です。
どうしても両眼視する必要もないと思うのですが、やはり没入感が欲しいのでステレオカメラにしたいところです。
幸い弊社には、StereoPiの新しいのと古いのとがあります。これを使えばステレオカメラはOKです。
また、PoCの足回りとしてルンバを使います。ルンバはUARTからコントロールができます。
UARTが使えてROSをお手軽につなぐには、やはりRaspberryPiを使うのが簡単です。そして幸いなことにStereoPiはRaspberryPiのコンピュートモジュールを使っています(V1はCM3、V2はCM4)。
というわけで、StereoPiでROSを動かしてやれば、ステレオカメラもUART制御も出来るということになります。
StereoPiはV1でもV2でも良いんですが、ここでV1を使ってやらないともうV1が使われることはなくなるんじゃないかという気がしたので、V1を使うことにしました。
ROSを入れるためにはUbuntuである必要があるので(他の環境でもやって出来ないわけじゃないですが)、V1にUbuntuを入れます。読めばわかると思いますが、以下の手順はV2でも同じはずです。
Ubuntuのインストール
うちにあるStereoPi V1に使われているCM3はeMMCのついているバージョンです。
このStereoPiに何かをインストールする時は、
USBケーブルでつないだStereoPiをSDのつもりでアクセスする
ことで出来てしまいます。つまり、RaspberryPiのイメージ作成ツールであるRaspberry Pi ImagerでStereoPiに書き込むだけです。
この辺の手順については、公式wikiの
Upload image to EMMC over Micro USB (CM1, CM3 non-Lite)
に書かれている通りにやれば出来ます。要するにSDのフリをするファームを書き込んでやるという話です。
どのUbuntuを入れるのだという話がありますが、今回はVer 22.04 32bit版です。Ver 22.04というのはROSの都合です。今現在の最新は23なのでそれを入れたくなるのですが、ROSを入れる時に苦労します(具体的には未サポートのOSに対応するくらい手間)。32bit版と言うのは、CM3はRaspberry Pi 3と同じですが、メモリは1GBしかありません。64bitであるメリットは特にないのと、64bit版だとカメラのユーティリティを改めて入れる必要があってミニマム環境を志すには邪魔(eMMCはそんなに大きくない)なので、32bit版を選択しました。どっちでも動くことは動くので、好きな方で構いませんけど。
イメージを書き込んで起動させると、普通にUbuntuが起動します。
カメラを動かす
このUbuntuの環境ではStereoPiのカメラは動作していません。
# vcgencmd get_camera
supported=0 detected=0, libcamera interfaces=0
これは標準カメラでも同じだったと思います(私は使ったことない)。
カメラを動かすためには、2つの作業が必要です。
- device treeを設定する
- ファームウェアの設定をする
ことです。
device treeを設定する
IA系のLinuxではあまり顔を出して来ませんが、ARM系のLinuxではdevice treeという仕組みでカーネルのデバイス情報を定義します。詳しいことは適当に調べて下さい。雑なことを言えば、ARM系だと「同じCPUでもハードウェアがチマチマと異なる」ということがあるので、その「チマチマと異なる」部分をちゃんと教えてやる必要があるわけです。
ハードウェア固有の情報は主にこのファイルに定義されています。より正確には、ソース形式のものを「コンパイル」したものが使われます。
このファイルは公式wikiで公開されています。
Device tree (DTS and dt-blob.bin)
ここからdt-blob.bin
を落として来てイメージに追加します。
どこに置くかが問題になるわけですが、置き場はUbuntuの場合は/boot/firmware
です。公式wikiではこの辺雑なことが書いてあって、うっかり読むと/boot
かなと勘違いしてしまうのですが、それはRasbianの場合であってUbuntuの場合ではありません。UbuntuもRasbianもDebianの系統なのでこの辺同じだと誤解してしまうのですが、カーネルの起動のあたりはちょっと違うので注意が必要です。
ということで、「dt-blob.bin
を入手して/boot/firmware
に置く」ということでこの作業は完了です。
ファームウェアの設定をする
要するに起動パラメータを設定してやるわけです。
/boot/firmware/config.txt
を以下のようにします。
[all]
kernel=vmlinuz
cmdline=cmdline.txt
initramfs initrd.img followkernel
[pi4]
max_framebuffers=2
arm_boost=1
[all]
# Enable the audio output, I2C and SPI interfaces on the GPIO header. As these
# parameters related to the base device-tree they must appear *before* any
# other dtoverlay= specification
dtparam=audio=on
dtparam=i2c_arm=on
dtparam=spi=on
# Comment out the following line if the edges of the desktop appear outside
# the edges of your display
disable_overscan=1
# If you have issues with audio, you may try uncommenting the following line
# which forces the HDMI output into HDMI mode instead of DVI (which doesn't
# support audio output)
#hdmi_drive=2
# Enable the serial pins
enable_uart=1
# Autoload overlays for any recognized cameras or displays that are attached
# to the CSI/DSI ports. Please note this is for libcamera support, *not* for
# the legacy camera stack
#camera_auto_detect=1
#display_auto_detect=1
[cm4]
# Enable the USB2 outputs on the IO board (assuming your CM4 is plugged into
# such a board)
dtoverlay=dwc2,dr_mode=host
[all]
gpu_mem=128
start_x=1
ここで重要なのは、
gpu_mem=128
start_x=1
camera_auto_detect
はコメントアウトする
ということです。
前2つはいろんな情報からわかるのですが、最後のはちょっとハマりポイントです。このcamera_auto_detect
というのはRaspberry Piの「古いカメラ」のことなのだそうで、最近のカメラやStereoPiのようなサードパーティーのカメラには不要... と言うより邪魔です。
以上の2つでStereoPiのカメラが動きます。
動作確認
device treeやファームウェアの設定が正しいかどうかは、
# vcgencmd get_camera
supported=2 detected=2, libcamera interfaces=0
となることで確認ができます。
設定が間違っている場合はsupportedやdetectedが0になっています。
V4L的にどう認識しているか確認するには、
# apt install v4l-utils
# v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
/dev/video10
/dev/video11
/dev/video12
/dev/video18
/dev/video31
/dev/media2
bcm2835-isp (platform:bcm2835-isp):
/dev/video13
/dev/video14
/dev/video15
/dev/video16
/dev/video20
/dev/video21
/dev/video22
/dev/video23
/dev/media0
/dev/media1
mmal service 16.1 (platform:bcm2835-v4l2-0):
/dev/video0
mmal service 16.1 (platform:bcm2835-v4l2-1):
/dev/video1
のようにします。/dev/video0
や/dev/video1
がなければ、何かを間違えています。
これらが正しければ、
# raspistill -cs 0
とやればコンソールにカメラ画像が表示されるはずです。sshで入って作業していても、表示されるのはコンソールですから間違えないようにw
入れたUbuntuが64bit版だった場合は、このraspistillが存在していないので、他の方法で確認する必要があります。私はこの辺が面倒臭かったのと、どうせメモリは1GBしかないということもあって32bit版をインストールしなおしました。
これでUbuntu版StereoPiが出来ました。
まとめ
わかってしまえば簡単なことですが、結構時間がかかってしまいました。
そもそもStereoPiがマイナーなハードウェアなので、基本的に公式wikiにしかマトモな情報がありませんし、Raspberry Piでサードパーティーのカメラを使った話もあまりありません。ネットにある情報らしきものの多くは「たまたま動いた」みたいなものが氾濫していたり。久々に先駆者がいないところをやったなという感じです。
ただ、そういった時でも、個々の動作を考えつつ試行錯誤すること、ネットに情報を流す前に何をやったことが本質だったかということを整理することは大事だなと感じました。試行錯誤していると「やってみたけど意味がなかったこと」がそのまま残ったりしてしまうので、情報を公開するという前提でそういったことを消して行くというのは、本質の理解のためには大事なことですね。