Jetson Orin Nanoの使い始め(カメラ導入編)

## はじめに

さて、先日の記事[「Jetson Orin Nanoの使い始め(初期セットアップ編)」](https://qiita.com/MakotoA67/items/a4156d87fcfc5f621722)で予告した通り、今回は、Jetson Orin Nanoにカメラ(まずはメジャーなIMX219で)を接続して使用する方法を紹介したいと思います。

ちゃんと内容を整理してから公開しようとすると、どうにも中々公開までたどり着かないことが多いので、今回は、大体書けたら公開しつつ、手直しや補足説明の追加がしたくなったら、その都度、編集していこうと思いますので、この場で予告しておきますね。

## カメラとの接続、使用方法

Jetson Orin Nano開発者キットを購入して、まず初期セットアップを実施して、さあ、使えるようになりました、となって、次に、カメラを使いたいとなるとどうしましょうか。

Windows PCの場合、しかもノートPCだと最近は標準的にWebカメラが搭載されているので、すぐに、Google MeetやMicrosoft TeamsやSkypeなどで使えてしまうかと思います。デスクトップPCだと、購入時にちょっと意識してカメラオプションを付ける、ということになるでしょうか。また、WindowsではなくUbuntuなどのLinuxをPCに導入して使用している人は、Cheeseなどのカメラアプリがメジャーかなと思います。実際、WebカメラをUSBに接続し、cheeseアプリを起動すると、通常は特に苦労なくカメラが使用できるかと思います。

さて、今回、Jetson Orin Nano開発者キットで、**JetPack 6.0 DP**を導入してセットアップすると、インストールされているOSは**Ubuntu 22.04.03 LTS**となっているかと思います。

手元にある[Webカメラ](https://www2.elecom.co.jp/multimedia/pc-camera/ucam-dle300t/)をつないでcheeseアプリを実行すると、

```
$ cheese
JPEG parameter struct mismatch: library thinks size is 584, caller expects 720
```

などと言われてしまいます。

cheeseアプリをGUIの「お気に入り」登録しておいて実行すると、上記のエラーメッセージすら見えませんね。。。

大体、ラズパイとかJetsonなどのボードコンピュータは、標準的なものを動かしているはずが、こういう訳のわからない状況に陥ることが多いですよね。

ですが、ここは気を取り直して行きましょう。

### カメラとの物理的な接続

Jetson Orin Nano開発者キットを最初に動かすときは、まず、[Jetson Orin Nano Developer Kit Getting Started Guide](https://developer.nvidia.com/embedded/learn/get-started-jetson-orin-nano-devkit)あたりを参照して、まず初期セットアップして、その次は、その最後のページの[Next Staps](https://developer.nvidia.com/embedded/learn/get-started-jetson-orin-nano-devkit#next)にもリンクが載ってますが、[Jetson Orin Nano Developer Kit User Guide](https://developer.nvidia.com/embedded/learn/jetson-orin-nano-devkit-user-guide/index.html)あたりを参照して、次のステップを考えて行くのだと思います。

まず、カメラとして何を使うか、考えてみましょう。通常、PCの世界では、カメラはUSB接続のWebカメラが一般的ですが、ラズパイやNVIDIA Jetsonなどのボードコンピュータの世界では、MIPI CSI Cameraがよく使われていますね。[Jetson Orin Nano Developer Kit User Guide - Hardware Specs](https://developer.nvidia.com/embedded/learn/jetson-orin-nano-devkit-user-guide/hardware_spec.html)の⑨を見てみましょう。

ここでは、**Raspberry Pi Camera Module v2**のような**CSI camera module with 15-pin connector**と紹介されています。

![JetsonOrinNanoとIMX219](https://developer.download.nvidia.com/embedded/images/jetsonOrinNano/user_guide/images/jonano_with_IMX219.jpg)

Jetson Orin Nano開発者キットではじめてこの世界に入って来た人は、なんのこっちゃ？と思うところかと思いますが、Jetson Nanoやラズパイ4までは、**1mmピッチの15pinのコネクタ**が使われていましたが、Jetson Orin Nanoやラズパイ5などでは、**0.5mmピッチの22ピンのコネクタ**に変わったようで(私も今回知りました)、ここではそのことが書かれています。

ということで、私も、Jetson Nano開発者キットでの開発作業に入っていくときに、最初にリファレンスのカメラとしてお世話になった、**Raspberry Pi Camera Module v2**を接続して使ってみましょう。

まず、物理的に接続するには、Jetson Orin Nano Developer Kit User Guide - Hardware Specsの⑨にも書かれているように、[15-pin to 22-pin conversion cable(15ピン-22ピン変換ケーブル)](https://amzn.to/3vqE1uJ)が必要となります。

あるいは、今からカメラとケーブルセットで購入するのならば、[Yahboom IMX219 CSIカメラ](https://amzn.to/3vm82eZ)あたりを購入すればいいかと思います。


### カメラを使用するためのコンフィグレーション設定

これで、物理的には接続できます。

ですが、USBカメラとは違って、MIPI CSIカメラの場合は、それ用のドライバを組み込んだり、Device Treeに情報を設定したり、などという作業が必要となり、このあたりが敷居が高いと思います。

IMX219を使うためのDevice Tree上の設定からまずは行きましょう。

https://docs.nvidia.com/jetson/archives/r35.3.1/DeveloperGuide/text/HR/ConfiguringTheJetsonExpansionHeaders.html#configuring-the-csi-connector

このあたりを参照して、IMX219などを有効にします。

![Screenshot from 2024-01-01 16-02-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/60a721f5-5bda-e3c0-198a-82c6dea30787.png)

![Screenshot from 2024-01-01 16-03-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/6b27c38d-b4f3-1093-f13d-e66d1febb8bb.png)

![Screenshot from 2024-01-01 16-03-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/34d0d62a-6dba-ddcb-866a-ae211060157b.png)

この次に、以下の4つのオプションから選択する画面になります。

* Camera IMX219 Dual
* Camera IMX477 Dual
* Camera IMX477 Dual 4 lane
* Camera IMX477-A and IMX219-C

![Screenshot from 2024-01-01 16-03-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/0f09c5ec-b366-1430-f219-3b5407939a63.png)

上記のように、IMX219が一つだけ接続されている形態を示していると予想できるオプションを選択してみます。

![Screenshot from 2024-01-06 23-27-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/5b53983d-aabf-c9e4-e8cb-6192c5639187.png)

![Screenshot from 2024-01-01 16-04-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/3a4fbf78-3c8d-1ebc-fa44-fe844aa17863.png)


![Screenshot from 2024-01-01 16-04-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/6dda0ea1-8575-7018-4b0b-d0aae4188270.png)

ここでリブートした後、IMX219を、

* CAM0に接続したとき
* CAM1に接続したとき

のそれぞれで起動時のログを確認してみましょう。

![IMG20240108205732_rotated.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/af811982-59c3-f127-a8a6-470d58a10645.jpeg)

上記のようにCAM0に接続したときは、何やらimx219の検知処理が動いているようですが、その通信でエラーとなった感じです。

```
[   13.629712] imx219 9-0010: tegracam sensor driver:imx219_v2.0.6
[   13.640428] imx219 9-0010: imx219_board_setup: error during i2c read probe (-121)
[   13.645547] imx219 9-0010: board setup failed
[   13.645602] imx219: probe of 9-0010 failed with error -121
```

それに対して、

![IMG20240108200810_rotated.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/4688fbbc-0058-8741-8f6d-9bdbacfaf242.jpeg)

![IMG20240108200827.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/5cfa62ae-b5c8-9f22-ff0e-c3b7b6819d87.jpeg)

と、CAM1に接続したときは、

```
$ sudo dmesg |grep imx219
[   12.043550] imx219 9-0010: tegracam sensor driver:imx219_v2.0.6
[   12.065296] tegra-camrtc-capture-vi tegra-capture-vi: subdev imx219 9-0010 bound
```

というように、imx219用のセンサドライバが認識されたようなログメッセージが確認できます。

そして、imx477に関しても確認してみると、

```
$ sudo dmesg |grep imx477
[   11.986970] imx477 10-001a: tegracam sensor driver:imx477_v2.0.6
[   12.287627] imx477 10-001a: imx477_board_setup: error during i2c read probe (-121)
[   12.287660] imx477 10-001a: board setup failed
[   12.287741] imx477: probe of 10-001a failed with error -121
```

ということで、jetson-io.pyで選択したオプションは、IMX219をCAM1に接続することを想定したものだと思われます。

#### (2024/1/9追記)コンフィグレーションその二

上で、

* Camera IMX219 Dual
* Camera IMX477 Dual
* Camera IMX477 Dual 4 lane
* Camera IMX477-A and IMX219-C

のうち、"Camera IMX219 Dual"を選択しておけば、CAM0とCAM1のどちらに装着しても認識しました。

CAM0に装着したときの起動時のログは以下の通りです。

```
$ sudo dmesg |grep imx219
[   10.606249] imx219 9-0010: tegracam sensor driver:imx219_v2.0.6
[   10.618990] imx219 9-0010: imx219_board_setup: error during i2c read probe (-121)
[   10.624708] imx219 9-0010: board setup failed
[   10.624780] imx219: probe of 9-0010 failed with error -121
[   10.625069] imx219 10-0010: tegracam sensor driver:imx219_v2.0.6
[   10.641224] tegra-camrtc-capture-vi tegra-capture-vi: subdev imx219 10-0010 bound
```

この状態では、この次のセクションで、sensor-id=1の指定なしのデフォルトで動作しました。なので、結果的には、こちらの方がオススメですね、多分。

### カメラを使用するためのアプリケーションプログラム環境

実際に、このカメラモジュールを使用する方法ですが、今回、IMX219カメラモジュールをCAM1の方に装着すると正しく認識したようですので、以下のように、sensor-id=1をオプションとして付加します。

```
$ gst-launch-1.0 nvarguscamerasrc sensor-id=1 ! 'video/x-raw(memory:NVMM), width=1280, height=720, format=(string)NV12, framerate=(fraction)30/1' ! nvegltransform ! nveglglessink -e
```

![Screenshot from 2024-01-08 13-38-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/11767f0a-934d-601d-0aec-d450095747de.png)

あと、NVIDIA提供のドキュメントとして、[Taking Your First Picture with CSI or USB Camera](https://developer.nvidia.com/embedded/learn/tutorials/first-picture-csi-usb-camera)というページが見つかりました。

```
$ nvgstcapture-1.0
```

とすると、

```
nvbuf_utils: dmabuf_fd -1 mapped entry NOT found
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, threadExecute:694 NvBufSurfaceFromFd Failed.
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, threadFunction:247 (propagating)
ERROR on bus: by /GstPipeline:capture_native_pipeline/GstBin:cap_bin/GstNvArgusCameraSrc:nvarguscamerasrc0: CANCELLED
debug info:
Argus Error Status
```

などと言われて、正しく画像が得られませんね。--helpオプションで指定すべきオプションを探してみますと、

```
 --sensor-id                       Camera Sensor ID value
```

というオプションが見つかりますね。ということで、ここでも、IMX219カメラモジュールをCAM1の方に装着しているということで、以下のように、--sensor-id=1と指定します。

```
$ nvgstcapture-1.0 --sensor-id=1 
```

![Screenshot from 2024-01-08 13-34-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998321/1e673d54-d234-c1e5-2690-70ab882b17b9.png)


## おわりに

今回、なるべく、NVIDIAの標準的な情報で、必要な情報にたどり着けるようにと思って書いてみましたが、ちょっとまだ中途半端かな、と思います。また、追加情報を見つけるなどしたら、また後で徐々に、もう少し説明を追記していきますね。

また、次の投稿ネタですが、今回の記事を「カメラ導入編」とタイトルつけましたので、次は、「カメラ活用編」あたりかな、と思います。あと、Jetson Nanoのときも紹介していましたが、Linuxカーネルのビルド方法などについてにも、また触れてみたいと思います。では。