自動運転シミュレータLGSVLのPythonAPIをインストールしてサンプルプログラムを実行する

# はじめに
この記事では、自動運転シミュレータであるLGSVLのPythonAPIのインストール方法と、サンプルプログラムの実行方法、簡単な実装例を紹介します。
LGSVLのインストール方法と基本的な使い方はこちらの記事でわかりやすく紹介されています。ぜひ参考にしてください。
https://qiita.com/zacc/items/13c4e04bc04fb29c9aec

2020/05/21
PythonAPIを使った簡単な実装例を追記しました。
比例制御で目標速度を追従するようにスロットル制御します。

# 環境
- Windows10 64bit
- Core i7-8700K
- GeForce GTX 1080Ti
- Git 2.19.1.windows.1
- Python3.7
- LGSVL 2020.03

# Python APIのインストール
Python APIの公式ドキュメント：<https://www.lgsvlsimulator.com/docs/python-api/>
Python APIのリポジトリ：<https://github.com/lgsvl/PythonAPI>

Python APIのリポジトリをクローンしてインストールします。LGSVLのPython APIはPython3.5>=に対応しています。

```
git clone https://github.com/lgsvl/PythonAPI.git
cd PythonAPI
pip install .
```

# サンプルプログラムの実行
PythonAPIリポジトリにあるサンプルプログラムを実行してみます。サンプルプログラムは「quickstart」という名前のフォルダの中に入っています。

まず、LGSVLのブラウザから「Simulationsタブ」→「API Only」→「再生ボタン」の順にクリックします。
![python_api_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241001/0a97ef84-817d-1895-0a8e-abdfcab29f7f.png)

するとLGSVL Simulatorに「API ready!」と表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241001/ba5b24b0-245e-e605-bcf6-a0819a56ba63.png)


この状態でPythonAPIリポジトリにあるサンプルプログラムを実行します。

```
python ./quickstart/05-ego-drive-in-circle.py
```

以下のように表示されるのでEnterを押します。

```
Current time =  0
Current frame =  0
Press Enter to start driving
```

すると車両がひたすらぐるぐる回り続けます。
![out.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241001/6f304f43-6266-a8b5-d80a-2ee00a288120.gif)

# 実装例
ここでは比例制御を使って車両を目標速度を追従するようにスロットル制御してみます。コードは以下です。

```python
import lgsvl
import os
import numpy as np


def p_control(target_speed, current_speed):
    """
    比例制御
    :param target_speed: 目標速度
    :param current_speed: 現在速度
    :return: スロットル値
    """
    k_p = 0.05
    error = target_speed - current_speed
    throttle = np.clip(error * k_p, 0.0, 1.0)

    return throttle


if __name__ == '__main__':
    sim = lgsvl.Simulator(os.environ.get("SIMULATOR_HOST", "127.0.0.1"), 8181)

    # マップの読み込み
    # 障害物が何もないマップを指定します
    map_name = "WideFlatMap"
    if sim.current_scene == map_name:
        sim.reset()
    else:
        sim.load(map_name)

    # 車両をスポーンできる位置（transform）のリストを取得
    spawns = sim.get_spawn()

    # エゴ車の初期状態を決める
    state = lgsvl.AgentState()
    state.transform = spawns[0]
    # シミュレータにエゴ車を追加する
    ego = sim.add_agent("Lincoln2017MKZ (Apollo 5.0)", lgsvl.AgentType.EGO, state)

    # 目標速度[km/h]
    target_speed = 50.0
    # 制御周期[sec]
    time_step = 0.05

    while True:
        # 現在の速度[km/h]を取得
        # ここではy軸（地面に対して垂直）の速度は無視します
        state = ego.state
        current_speed = np.linalg.norm([state.velocity.x, state.velocity.z]) * 3.6

        # スロットル値を取得
        throttle = p_control(target_speed, current_speed)

        # エゴ車に制御値を適用
        control = lgsvl.VehicleControl()
        control.throttle = throttle
        ego.apply_control(control, True)

        # シミュレータの時間をtime_stepだけ進める
        sim.run(time_limit=time_step)

        # 現在の速度をコンソールに出力
        print("Current speed: {:.1f} [km/h]".format(current_speed))


```

こちらのコードを上記のサンプルプログラムの実行手順と同様に実行していただくと、指定した目標速度で直進します。

# おわりに
PythonAPIを使えば車両の制御、センサ情報の取得などいろんなことができます。
LGSVLはAutowareなど自動運転ソフトウェアと連携できるようですが、PythonAPIを使ってオリジナルの自動運転車を作ることもできると思います。
これからLGSVLのPythonAPIを使ったに関する記事を書いていけたらと思います。
簡単な説明でしたが以上です。ほかにもいろいろサンプルプログラムが入っているので試してみてください！