nuPlanのチュートリアルを動かしてみる

## はじめに

本記事では、世界初の大規模な自動運転の運動計画ベンチマークnuPlanのチュートリアルをUbuntuで動かしてみました。いくつか解決する事項があったので、その動かし方について紹介します。

## nuPlanについて

![](https://www.nuplan.org/static/media/nuPlan_final.3fde7586.png)

[nuPlan](https://www.nuscenes.org/nuplan)は機械学習ベースの自動運転用の運動計画プランニングを閉ループで評価することのできる世界初のベンチマークです。nuPlanは機械学習ベースのプランナーを開発するため、モデルの訓練フレームワーク、軽量な閉ループシミュレーター、交通違反や快適性を評価するメトリック、結果を視覚的に表示するビジュアライゼーションで構成されます。nuPlanのコア部分であるシナリオシミュレーションはモジュール化されており、カスタマイズ可能なように設計されています。この設計と、USおよびアジアの様々な交通パターンを含む1500時間の運転データを使って効率的にプランナーを開発することできます。

さて、nuPlanの[Get Started](https://nuplan-devkit.readthedocs.io/en/latest/README.html)にしたがってチュートリアルを実行します。

## データセットのダウンロード

初めに[データセットアップ](https://nuplan-devkit.readthedocs.io/en/latest/dataset_setup.html)に従って[ダウンロードページ](https://www.nuscenes.org/nuplan#download)からnuPlan v1.1 Datasetの次の２つのファイルをダウンロードします。

* nuplan-maps-v1.0.zip
* nuplan-v1.1_mini.zip

そして次のファイル構造になるように解凍したファイルを配置します。

```bash
├── exp
│   └── ${USER}
│       ├── cache
│       │   └── <cached_tokens>
│       └── exp
│           └── my_nuplan_experiment
└── dataset
    ├── maps
    │   ├── nuplan-maps-v1.0.json
    │   ├── sg-one-north
    │   │   └── 9.17.1964
    │   │       └── map.gpkg
    │   ├── us-ma-boston
    │   │   └── 9.12.1817
    │   │       └── map.gpkg
    │   ├── us-nv-las-vegas-strip
    │   │   └── 9.15.1915
    │   │       └── map.gpkg
    │   └── us-pa-pittsburgh-hazelwood
    │       └── 9.17.1937
    │           └── map.gpkg
    └── nuplan-v1.1
        ├── mini
        │   ├── 2021.05.12.22.00.38_veh-35_01008_01518.db
        │   ├── 2021.06.09.17.23.18_veh-38_00773_01140.db
        │   ├── ...
        │   └── 2021.10.11.08.31.07_veh-50_01750_01948.db
        └── trainval
            ├── 2021.05.12.22.00.38_veh-35_01008_01518.db
            ├── 2021.06.09.17.23.18_veh-38_00773_01140.db
            ├── ...
            └── 2021.10.11.08.31.07_veh-50_01750_01948.db
```

配置後、次の環境変数をexp, dataset, mapsのそれぞれのパスの環境変数を`.bashrc`に追加します。この環境変数が設定できてない場合、訓練や実験で失敗をします。

```shell
export NUPLAN_DATA_ROOT="${データを配置したディレクトリ}/dataset"
export NUPLAN_MAPS_ROOT="${データを配置したディレクトリ}/dataset/maps"
export NUPLAN_EXP_ROOT="${データを配置したディレクトリ}/exp"
```

## 仮想環境の作成

[ nuplan-devkit](https://nuplan-devkit.readthedocs.io/en/latest/index.html)のドキュメントにしたがい、[miniconda](https://conda.io/en/latest/miniconda.html)（もしくはanaconda）をインストールします。インストール後、リポジトリをクローンし、仮想環境を作成します。

```shell
git clone git@github.com:motional/nuplan-devkit.git
cd nuplan-devkit
conda env create --prefix .venv -f environment.yml 
```

> 注）2022年11月7日時点でmasterブランチで仮想環境を作成したところ、bokeh 3.0.1がインストールされました。bokeh3.0.1であるとチュートリアルを実行するときにエラーが出るようです。正しくはbokehのバージョン2.4.2にする必要があります。`requirements.txt`のbokehの行を`bokeh==2.4.2`に変更して仮想環境を作りました。

## VS Codeの設定

チュートリアルは`nuplan-devkit`リポジトリ直下の`tutorials`ディレクトリに入っています。今回は`nuplan_framework.ipynb`を実行します。

```
.../nuplan-devkit
├── nuplan  <---------------------------------------------モジュール
├── tutorials
│   ├── media
│   │   ├── nuplan_flow.svg
│   │   └── planner_inputs_outputs_diagram.drawio.svg
│   ├── nuplan_advanced_model_training.ipynb
│   ├── nuplan_framework.ipynb  <-------------------------これ
│   ├── nuplan_planner_tutorial.ipynb
│   ├── nuplan_scenario_visualization.ipynb
│   ├── test
```

VS Codeで`nuplan-devkit`をワークスペースとして開いてそのままノートブックを実行すると、`tutorials`がノートブックの実行場所となるため、パラメータ管理ライブラリである`Hydra`が`nuplan`のモジュールの場所を見つけることができません。この場合、ノートブックの`Prepare the training config`で次のようなWarningとExceptionが出力されます。

```
..../nuplan-devkit/.venv/lib/python3.9/site-packages/hydra/_internal/config_loader_impl.py:213: UserWarning: provider=hydra.searchpath in main, path=nuplan.planning.script.config.common is not available.
  warnings.warn(
..../nuplan-devkit/.venv/lib/python3.9/site-packages/hydra/_internal/config_loader_impl.py:213: UserWarning: provider=hydra.searchpath in main, path=nuplan.planning.script.experiments is not available.
  warnings.warn(
```

```
ConfigCompositionException: You must specify 'training_metric', e.g, training_metric=<OPTION>
Available options:
	agents_avg_displacement_error
	agents_avg_heading_error
	agents_final_displacement_error
	agents_final_heading_error
	avg_displacement_error
	avg_heading_error
	final_displacement_error
	final_heading_error
```

これを防ぐためにJupyterの実行場所を`settings.json`に追加します。

```shell
"jupyter.notebookFileRoot": "${workspaceFolder}"
```

また`nuplan_framework.ipynb`をVS Codeで開いて、作成した仮想環境でノートブックを動かすように設定します。

## チュートリアルの実行

「**Run All**」を押して`nuplan_framework.ipynb`を実行します。実行すると機械学習モデルの訓練、シミュレーション、評価、そしてシミュレーション結果の可視化が行われます。ノートブックの最後まで実行が終わると`nuBoard`がWebブラウザを通して立ち上がります。
![nuBoard初期画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122513/419b73b3-1552-e9f2-64b6-b5ec96edcf59.png)

`nuplan_framework.ipynb` の**Simulate a trained ML planner for comparison**のステップでは初期設定の場合、多くのRAMを消費します。これは`Ray`を使って並列にシミュレーションを実行しているためです。私の環境だと使用量が90%を超えたため、以下の変更を行い、並列オプションをオフにしました。

```yaml
# nuplan/planning/script/config/common/default_common.yaml
Old
  - worker: ray_distributed
New
  - worker: sequential
```

次に`nuBoard`の左パネルにある「Scenarios」をクリックします。そうすると次の画面が出力されます。
![nuBoard初期画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122513/c04b22af-e5b5-63fa-9583-b57304a0854e.png)

右上の歯車アイコンをクリックして、`Scenario Token`を選択します。
![scenario token選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122513/7e38886f-b135-3227-7a6d-cab5d0c9f385.png)

そうすると選んだシナリオがロードされ、次のような画面に更新されるはずです。
![Scenario選択後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122513/87be57ad-2129-a68f-0a69-d9776ddf47f2.png)
シークバーを動かしたり、左側のアイテムをトグルすることでシミュレーションの様子を確認できます。

## 参考ページ

[nuPlan](https://www.nuscenes.org/nuplan)