大破雑記帳

個人用メモな雑記ブログ いろんなことをざっくりと。

OpenWrtで車載撮影環境を構築してみる

これは mstdn.maud.io アドベントカレンダー 19日目の記事です。昨日は @unarist 氏でした。

adventar.org


(記事作成がギリギリになっているので、画像などは後から追加していきます...)

発端

まず車を買ったこと。

今年(2025年)の7月はじめに唐突に「夏の間に車で色々なところに出掛けてみたい」と思い立ち、そのまま選定と現車確認、購入着手と進み、下旬に納車。

この辺は別記事でもう少し詳しく書いているのでここまでとして、当初目的通り色々な場所に行く中で、「運転中に見た景色を見直してみたい」と思ったのと、単純に興味があったことから、車載動画の撮影をやってみよう、ということに。

車両

スズキ エブリイのOEMである、日産 NV100クリッパー (DR17V)。

当初より、助手席のインパネエアバッグ下にあるコンソールに、機材の一部を置く方向で考えていた。

方向性

車載動画の撮影、と考えた時に、まず思い浮かぶのはやっぱりアクションカメラ。振動の補正であったり、持ち運びや固定方法のオプションの多様さであったりなど動きのあるものの撮影に最適化されており、恐らくベストと言っても良いと思われる。

ただ、突き詰めたものであるが故に比較的高価になりがちで、「とりあえずやってみたい」という段階である自分にとってはやや過剰投資に感じたこと、あとは大体以下のような理由から、アクションカメラは除外した。

  • 最適化されたものをそのまま使うだけでは面白味が無かった(?)
  • SATA SSDなど手元の既存のストレージ類を活用できないか

そして最終的に、内部にSATAストレージを接続でき、OpenWrtを動作させられるデバイスによって、車載動画の撮影にトライしてみよう、ということに決定。

実現方法

まず、上で挙げた "内部にSATAストレージを接続でき、OpenWrtを動作させられるデバイス" というところで、ほぼNAS一択となる。(一部でNAS機能を持つルータというのが存在しなくもないが)

それを中心として、とりあえずざっくりと構成を考えてみると

  • 撮影制御とデータの記録/保管: NAS機種
  • 映像の撮影: Webカメラ
  • 音声録音: Webカメラ付属マイク?
  • 記録媒体: SATA SSD
  • コントローラ: テンキー
  • 電源: USB-C Power Delivery

となった。

音声については正直この段階ではそれほど思考が及んでおらず、「Webカメラのマイクで普通に録れるべ」くらいの認識で居た。後述するが、後にだいぶ悩まされることとなる。

コントローラとしてのテンキーについては、OpenWrtにおいては入力デバイス (HID等)からの入力を受け取ってボタン入力のイベントを発生させるドライバである button-hotplug ドライバ(パッケージ名: kmod-button-hotplug)が存在しており、これを改変することで、元々このドライバ内で対象としているキーコード以外も取ることができ、テンキーに使用されているキーでも任意のコマンドを割り当てることができると推測し、これを採用することとした。

機材選定

開発

まずはHDL-TAのOpenWrtサポートを実施。

ハードウェア面ではRTCチップにバッテリが無く、せっかくの時刻が保持できない点が気になるものの、それ以外は特に癖は無し。ソフトウェア面では、ブートローダが標準でUSBストレージからもブートが可能な仕組みになっていたのでオッと思ったものの、特定条件下でSATA/USB両方ともブートがコケる謎現象を抱えており、やや強引に対処。詳しいことは本題から外れるので今回は割愛。

HDL-TAのサポートが大体満足いく状態になったところで、本題である撮影の制御周りに着手。

Cで書いてみるか一度悩んだものの、とにかくシステムとして動く状態に最速で持って行く為、ShellScriptで書いていくことに決定。Linux環境下でWebカメラを使用し映像を撮影する為に必要なソフトウェア関係を調べてffmpegやその他を導入の上、ffmpeg等に投げ込む引数などを実機で何度も試しつつ制御用コードの改善を重ねた。

撮影時に使用するビデオデバイス (/dev/videoN)や解像度、フレームレートなどプロファイルについてはOpenWrtのコンフィグファイルを作成し、設定システムであるUCIを介して設定の参照や変更をできる形としたり、テンキーのキー操作で撮影に使用するプロファイルを呼び出せる形で実装した。

そうこうしてなんとかアパート内にて最低限テンキーによる撮影開始/停止を行える状態に到達した。

全体写真

写真は以下の "改善試行" で外部マイクを接続していた際のもので、テンキーのUSBハブ右側ポートに接続されているサウンドバイスとマイクは現在無し。HDL-TAから生えている青/白/黒のケーブルはUART。

Post by @musashino205@mstdn.maud.io
View on Mastodon

実車テスト

アパート内で大体動作する状態になったので、実際に車に搭載して撮影をテスト。

車両のアクセサリーソケットに充電器を接続し、HDL-TAはクリッパーの助手席前方にあるエアバッグ下のコンソールに配置。コントローラであるテンキーをHDL-TAのUSBポートに接続して助手席に置き、Webカメラはテンキーのハブに繋げて助手席ヘッドレストのポールに別途調達したカメラ用アームで固定。

この状態で実際に撮影しながら走り回った。

Post by @musashino205@mstdn.maud.io
View on Mastodon

結果

  • 昼間

    • 映像の鮮明度としては総じてそれほど問題無し。静止画で見るとやや粗さを感じるものの、映像としては60fpsにすると比較的それほど気にならずに見れる。
    • 画面内に明るさの差が大きい箇所がある場合、明るい場所は白く飛びがち。空は青が飛んで白くなってしまっていて、撮影の動機の一つであった "運転中に見た景色を見直してみたい" という点から考えると少々ズレてしまう。
  • 夜間

    • 映像が目で見たものと比べ、暗くなってしまう。街灯は真っ黒な中に浮かぶ状態で、前照灯も実際よりだいぶ手前までしか映っていない。
  • 共通

    • Webカメラが本来室内で使うことを前提としているせいか、度々フォーカス調整が入り、画面内がボヤける。特に夜間は昼間よりも回数がやや多いようで、暗いがために距離を掴みづらそうである。
    • 音に雑音が大量に入る。路面の凹凸が多い場所で多く、停止中や凹凸の少ない場所では発生しない。これについては後述。

以下はテスト時とは別の機会に撮ったものの、夜間の映像の暗さと雑音の多さはわかりやすい:

Post by @musashino205@mstdn.maud.io
View on Mastodon

改善試行

  • 昼間

    • 明るさの差による明るい範囲の白飛び

      → UVC (USB Video Class)パラメータの明るさやコントラスト、ガンマ値の調整

      実車にてUVCパラメータを調整し、空の青さなどをしっかり映るよう調整。ただ、その結果車内など暗い範囲は更に暗くなってしまう為、この辺りは自身の許容できるバランスで妥協する必要がある。UVCパラメータには逆行補正 (Backlight Compensation) も存在するものの、これは暗い箇所を基準に明るさを上げるので今回は微妙。

  • 夜間

    • 映像の暗さ

      → 昼間同様にUVCパラメータの明るさやコントラスト、ガンマ値の調整

      こちらも実車にてUVCパラメータを調整し、できるだけ目で見た状態に近付けた。ただ、暗くて黒く潰れてしまう範囲を明確にするにはコントラストをだいぶ弄る必要があり、はっきりとした黒さの表現が失われてやや白っぽくなってしまう。この辺りも自身の許容範囲で妥協する必要がある。

  • 共通

    • フォーカス調整

      焦点距離もUVCパラメータにて設定が可能なので、自動調整を外して適切な距離を設定する。これも実車にて、カーナビの時刻やスピードメーターが、ややボヤけても大体読み取れ、正面車外の風景も問題無い程度に調整した。

      ちなみに、これと上述の明るさ, コントラスト, ガンマ値の調整を実際の映像を見ながら行えるよう、mjpg-streamerを利用してストリーミングを起動する機能の実装も行った。加えて、パラメータ調整を当初HDL-TAを起動するたびに行っていたものの、あまりに手間だったので、パラメータの組み合わせをプロファイルとして管理し、コントローラ代わりのテンキーからキー操作で適用できるようにした。

    • 大量の雑音

      → 正直これが一番原因の特定に難航した。路面の凹凸による振動由来であることは確かであるものの、ならばそれがWebカメラ周辺で振動して雑音となっているのか、それとも他の振動を拾っているのか、そして素で入ってくる音がこの雑音であるのか、などが当初全く不明だった。

      一旦外部マイクやそれを接続するマイク入力付きのUSBサウンドバイスを調達してみるも、そちらはいまいちエンジン音など車内の音をまんべんなく拾うことができず、結局Webカメラ内蔵マイクの方がまんべんなく(現状ノイズ含め)拾っていることからそちらに回帰し、試行錯誤を重ねた。

      結果として、防振ゴムでの対処を行ってみるもほとんど変化が無いことから音自体は他からそのまま来ているものと判断し、マイクでハードウェアとして設定された入力レベルが高すぎ、振動によるノイズが入った際の波形の頂点で許容値を振り切って瞬間的に音割れしているようだ、ということが判明。

      そこで、alsamixer を使用してWebカメラ内蔵マイクのハードウェアとしての入力レベルを多少下げ、下げた分の音量を ffmpeg において -af volume=+NdB を渡すことでソフトウェア的に上げてみたところ、いくらか音割れノイズの低減を確認。これについてはまだ調整中で、適切な設定値を見付けられたら比較の為撮影するなどしてみたい。

      ちなみに、サウンドバイスのハードウェアとしての入力レベルはデバイス側で保持されるのか、デバイス側の電源が切れると初期値に戻る(≒エンジン始動によるHDL-TA起動時に初期値に戻る、電源保ったままHDL-TAを再起動した場合は設定値そのまま)為、OpenWrtのブートプロセス最後に実行される /etc/rc.local にて、alsactl を使用して音量設定後のコンフィグを適用することで設定し直している。

      また、音割れ対策として -afloudnorm なども試してみたものの、こちらはどうもHDL-TAのSoCの性能が足りていないようで、撮影時のffmpegによる音声エンコード時に処理速度がどうしても1倍に足りず、最大でも0.8倍程度をうろうろしてリアルタイムに追いつかないことから、やむなく断念。

今後

今後としては、上で挙げたとおり音声周りの調整と、昼間における明るさの調整を少し、それと制御用コードの改善というところ。現状では初期の "とにかく動くようにする" という点を引きずっていて、エラー処理などが最低限なので、その辺も改善したい。あとはCに書き換えて負荷の低減などもアリか。

その他には、現状音声はWebカメラのマイクを利用しており、モノラルであることから、ステレオで録るために対応しているサウンド入力デバイスを調達してみるのを思案中。マイク選びは難航しそうである。ちなみに、Amazonやそこらで大量に転がっているサウンドバイスのほとんどは、ステレオでのマイク入力に対応していない。

また、今回は "手元の既存資産を活用して安く抑える" という点を重視した為HDL-TAを採用したものの、正直なところ日産クリッパーの助手席コンソール部分には大きすぎてだいぶはみ出している。経済的な余裕が出たら、SBC系統と大容量MicroSDカードを使用するなどして、コンパクトに仕立ててみるのも思案中。ちなみに、より高性能なCheck Point V-80で外付け2.5インチストレージケースやUSB 3.0ハブを使用して組んだ環境でのテストも行ったものの、こちらは振動その他によるUSB接続部の接触不良により、SSDやカメラ等の認識が外れるトラブルが何度か発生した為、断念した。


というわけで、アドカレ19日目の記事でした。20日目は kb10uy 氏です。