NVIDIA Orinを使って、GMSL2カメラを入力して使う(Sensing TECH SG8A)

　……昔、自動運転系の仕事に関わると、やはり予算があるので相当なマシンを使用しているケースが多々あったのだが、世の中常にそんなことはないよなぁ、と感じる。
 
 ## NVIDIA Jetson AGX Orin Development Kitと自動運転
　そもそもNVIDIA Jetson AGX Orin(以下Orin)とは？　……という記事はいくらでも探せるので割愛。

　気になるのは、この機材を使っている場所はあるのか？　実績があるのか？　という件だろうか。

:::note info
色んなところでOrinは使われているので、どんどん使ってみよう
:::

　私の知っている範囲では、幾つかの大きなメーカーの開発部門で、Orinを使用している例を見てきている。なので、十分な性能があり、入手性がよくて、やりたいことができると見てよい。
　ただし、幾つかの要素には難儀していることも聞いている。
 + 耐震性。本体自体は問題ないが、PCIeにカードを刺した場合に問題が起こる恐れがありそう。
 + 耐熱性。精々70度の使用温度範囲だが、車両の搭載位置・環境によっては、厳しく問題が発生している。
 + 拡張性。搭載しているのは、PCIe(Gen4 x8)、M.2 SSDスロット、10GbE、USB。
 + 操作性。スイッチなどは延長できない。
 + 不良？　GPIOが反応しないものがある？(テストしたわけではないが、そう云われている)

　なので、各社割と工夫して(筐体を作成したりして)対応している印象がある。

 ## Sensing TECH SG8A-ORIN-GMSL2
 <img witdh="100" src="https://50002352.s21i.huaweicloudsite.cn/4/ABUIABAEGAAgn-ubvQYosLm08AEw1go4gQg.png">

　写真から、"逆さにつけるのかよ！"と突っ込みがあるかもしれないが。Orinのこの位置に繋ぎ、さらにカメラ配線(Fakraコネクタ)、電源、同期用回路を接続するためこうなる。……フレームなどを製作すれば、Orinの下にハーネスを出すようにできる。

　[ここ](https://store.sgwrd.com/products/jetson-agx-orin-8-way-gmsl2-camera-adapter-board)から購入できる。但し、法人で買うなら問い合わせをしてからカメラと一緒に買うとよい。~~営業は親切でした。~~

　使うためのドライバなどは、[Gitにて公開されている](https://github.com/SENSING-Technology/nvidia-jetson-camera-drivers)。ここを読むと、対応しているカメラが書いてある。カメラの起動方法も書いてあるので、それに従えばとりあえず動かすことは比較的容易。ただ、Orinのバージョンが一致しない場合は、OrinのDriveOS？ JetPack？ のバージョンを変える必要がある。
 　また、IMX490などは8カメラまで対応するが、4Kカメラはデータ量が多いので7カメラまでに制限されることに注意されたい。

　また、カメラによって映像の同期の可否が設定されている。
　使い方は、[ここのページに書かれている](https://autosensee.feishu.cn/docx/FZMzd9fFTooYJ7xea3LcAe1Oneh)。ページ内に示されたカメラでは同期動作OK。ただ、自分はここに書いていないカメラ([SG5-IMX490C-5300-GMSL2](https://www.sensing-world.com/en/h-pd-24.html?recommendFromPid=0&fromMid=1544))だったが、同期機能を確認できた。
　同期には、PPS信号(GNSS装置などからの入力)が必要になる。

:::note info
Gitの手順通りやれば、とりあえず画面にカメラ映像がでます。簡単に。
:::

## アプリケーションで、カメラ映像を使う方法は？
　ハードウェアの担当者がここまで用意しても、アプリ担当者は映像が何かしらの形式で使えるようにならないと、クレームが来る。PythonでもC++でも、何かしらの……~~おんぶにだっこ、しないとダメ？~~

　一応、C++での実装は以下のように……OpenCVで使えるようなところまでのコードは実装した(以下は一部分)。

 ```cpp:sample.cpp
 std::string pipeline = "nvarguscamerasrc sensor-id=0 ! video/x-raw(neniry:NVMM),width=2880,height=1860,framerate=30/1,format=NV12 ! nvvidconv ! video/x-raw, format=YUY2 ! appsink";
cap = cv::VideoCapture(pipeline);
cv::Mat frame;
cap >> frame;
 ```
　あとはframeから表示するなり、で動作している。もちろんこれ単体では動かないので、OpenCVを準備したり、C++で画面表示させたり。
　このコードはROS2で使っていたものです。さすがに色々抜粋できないので。

 　注意点としては、これを使うとき、**そのままでは動きません**。なぜかというと、OpenCVをダウンロードしたそのままでは、**一部機能が無効化されています**。なので、ビルドオプションを設定して、一回ビルドが必要です。

```
# 1. 必要なパッケージをインストール
sudo apt update
sudo apt install -y build-essential cmake git pkg-config \
    libjpeg-dev libtiff-dev libpng-dev \
    libavcodec-dev libavformat-dev libswscale-dev \
    libv4l-dev v4l-utils \
    libxvidcore-dev libx264-dev \
    libgtk-3-dev \
    libcanberra-gtk* \
    libatlas-base-dev gfortran \
    python3-dev python3-numpy \
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev

# 2. OpenCVとcontribのソースを取得
cd ~
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git

# 任意でバージョン固定（例: 4.8.0）
cd opencv && git checkout 4.8.0 && cd ..
cd opencv_contrib && git checkout 4.8.0 && cd ..

# 3. ビルド用ディレクトリを作成
cd ~/opencv
mkdir build && cd build

# 4. cmakeでビルド構成（GStreamerとV4Lを有効にする）
cmake -D CMAKE_BUILD_TYPE=Release \
      -D CMAKE_INSTALL_PREFIX=/usr/local \
      -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
      -D WITH_GSTREAMER=ON \
      -D WITH_V4L=ON \
      -D WITH_1394=OFF \
      -D WITH_FFMPEG=OFF \
      -D BUILD_opencv_python3=ON \
      -D BUILD_opencv_python2=OFF \
      -D BUILD_NEW_PYTHON_SUPPORT=ON \
      -D BUILD_EXAMPLES=OFF ..


# 5. ビルド（時間がかかります）
make -j$(nproc)

# 6. インストール
sudo make install
sudo ldconfig
```

　これはOrin上で実行することを考慮して、Ubuntuで実行できるコマンドとしています。
　ちなみに、途中で1394とFFMPEGを無効にするオプションを設定しています。確か……GStreamerと競合してしまう？　という話があり、使用しないので無効化しています。

　コードを改良すれば、各カメラ映像を、C++で使用することができるようになると思います。更にうまく使えば、Pythonでも使えると思います。
　これで……GMSL2カメラを、Orinで手軽に映るようにできる。ハズ。

### おわりに
　OrinはNVIDIA製品で、当然GPU相当のSoCが乗っているので、色々AI処理などを実装できると思います。私はそこの専門ではないので、何をどうするという目標はないですが、GPIOにはCANもあるし、シリアル通信もできるので、簡単な自動運転ぐらいはできるような性能はあるんじゃないかなーと思っています。
　まあ、実際の自動運転ECUでは、もっと高性能な……Drive AGXを使います。大体Intel CPUぐらいのサイズのNVIDIA SoCを、自動運転ECUに表面実装します。なのでもっと高性能なはず。ですが、まあ開発とかならこれでもいいでしょう。
　でも、これはSensing TECHのボードでカメラの接続を楽に実現していますが、実際は自分らで作りこむので、そもそも液晶で映像は確認できないし、色々便利機能を省略するので大変です。~~正直もうやりたくない~~。しかし大事なことなので、やる機会があれば、私もまたいつか……

今日はここまで。