この記事の対象者
- 自動運転AIチャレンジ2023(simulation大会)に参加しており、planning機能追加など試行錯誤に取り組み中である
- planning機能追加など試行錯誤は楽しいが、機能評価1回あたり数分ほど掛かることがしばしば辛いことがある。シミュレータやrvizのGUIの見るべき箇所をしばしば見逃してしまう。ジャッジサーバ提出前に同じコマンドを何度も実行してるとしばしばコマンドミスして精神衛生上よくない。同じ作業を繰り返し実行する場合は自動化すべきであるの教えに感銘を受けたことがある方。など
- 「テスト書いてないとかお前それ、@t_wadaの前でも同じこと言えんの?」
シミュレータ+AWSIMを自動実行したい
自動運転AIチャレンジ2023(simulation大会)では、planning機能追加など試行錯誤がやりやすい環境が提供されております。
これまでの大会では基本的にはautowarefoundationのautowareを参照し、標準モジュールやそれらparameterを調整することが勝利への近道でありましたが、今回はよりシンプル構成であるautoware-microが提供されており、autowareの標準機能やparameterを調整するというよりかは、PythonRoboticsのモジュールや独自の工夫を取り入れること、および、試行錯誤を繰り返すことが競争ポイントとなりそうです。
ジャッジサーバ提出前に同じコマンドを何度も実行するのが辛くなってきたよ
独自の機能を追加するのは往々にして夜中になりがちです。しかしながら、夜中2時に目をこすりながら同じコマンド実行繰り返すのはミスが起きやすく、睡眠時間に影響を及ぼします。ここで自動化を活用することで解決を試みます。
というものの、以下の部分をスクリプト化するだけなのでシンプルです。せっかくなのでresult.json
まで確認できると便利そうです。
事前準備(aichallenge_submitの圧縮や結果出力用フォルダの生成)
#aichallenge2023-racingディレクトリで cd docker/evaluation bash advance_preparations.sh
dockerイメージのビルド
#aichallenge2023-racing/docker/evaluationディレクトリで bash build_docker.sh
dockerコンテナの起動(起動後、自動でautowareが立ち上がり、自動運転が開始されます)
GPU版のAWSIMを使っている方は#aichallenge2023-racing/docker/evaluationディレクトリで bash run_container.sh
result.jsonの確認
評価完了後、outputフォルダに以下のファイルが格納されます。
- result.json
- rosbag.db3
- rviz_capture.mp4
- autoware.log
シミュレータ+AWSIMを自動実行したいスクリプト(autorun.sh
)の概要
実行方法
前提条件
- SetUp手順に沿って各種インストール/事前準備完了していること
- 同様に、autowareのサンプルコードの手動実行が確認できていること
-
${HOME}/aichallenge2023-racing
ディレクトリが存在していること
今はGPU版のみ対応
実行コマンド
# スクリプトのダウンロード
cd ${HOME}/aichallenge2023-racing
wget https://raw.githubusercontent.com/seigot/aichallenge-tools/main/aichallenge2023-sim-winter/autorun.sh
wget https://raw.githubusercontent.com/seigot/aichallenge-tools/main/aichallenge2023-sim-winter/stop.sh
# シミュレータ+AWSIMを自動実行、二回目以降はここだけ実行してもOK
bash autorun.sh -l 100
結果
${HOME}/aichallenge2023-racing/result.txt
に結果一覧を出力するようにしており、別ターミナルからこれを参照するとよい。以下のようなログが出力されるはず。
(されなかったらごめんなさい、今はGPU版のみ対応)
$ cd ${HOME}/aichallenge2023-racing
$ tail -f result.txt
Player rawLapTime distanceScore lapTime isLapCompleted isTimeout trackLimitsViolation collisionViolation
20231229123146_automotiveaichallenge_main 248.398743 100 353.398743 true false [ 3, 6, 4, 1, 0] [ 2, 0, 0, 0]
20231229124031_automotiveaichallenge_main 248.6506 100 363.6506 true false [ 4, 7, 4, 1, 0] [ 2, 0, 0, 0]
20231229124856_automotiveaichallenge_main 231.108246 47.77975 381.108246 false false [ 6, 10, 5, 1, 0] [ 2, 0, 0, 0]
20231229125602_automotiveaichallenge_main 128.798477 47.51332 273.798462 false false [ 5, 8, 5, 2, 0] [ 2, 0, 0, 0]
...
シミュレータ+AWSIMを自動実行したいスクリプト(autorun.sh
)の中身
省略
N=2で動作確認済、今後もスクリプト更新していくかもしれません
https://github.com/seigot/aichallenge-tools/blob/main/aichallenge2023-sim-winter/autorun.sh
#!/bin/bash -x
#
# 自動実行用のスクリプト
# README記載のOnline提出前のコード実行手順をスクリプトで一撃でできるようにしてる
LOOP_TIMES=10
SLEEP_SEC=180
# check
AICHALLENGE2023_DEV_REPOSITORY="${HOME}/aichallenge2023-racing"
if [ ! -d ${AICHALLENGE2023_DEV_REPOSITORY} ]; then
"please clone ~/aichallenge2023-racing on home directory (${AICHALLENGE2023_DEV_REPOSITORY})!!"
return
fi
function run_autoware_awsim(){
# MAIN Process
# Autowareを実行する
# run AUTOWARE
AUTOWARE_ROCKER_NAME="autoware_rocker_container"
AUTOWARE_ROCKER_EXEC_COMMAND="cd ~/aichallenge2023-racing/docker/evaluation; \
bash advance_preparations.sh;\
bash build_docker.sh;\
rocker --nvidia --x11 --user --net host --privileged --volume output:/output --name ${AUTOWARE_ROCKER_NAME} -- aichallenge-eval" # run_container.shの代わりにrockerコマンド直接実行(コンテナに名前をつける必要がある)
echo "-- run AUTOWARE rocker... -->"
echo "CMD: ${AUTOWARE_ROCKER_EXEC_COMMAND}"
gnome-terminal -- bash -c "${AUTOWARE_ROCKER_EXEC_COMMAND}" &
sleep 5
}
function get_result(){
# 起動後何秒くらい待つか(sec)
WAIT_SEC=$1
# wait until game finish
sleep ${WAIT_SEC}
# POST Process:
# ここで何か結果を記録したい
AUTOWARE_ROCKER_NAME="autoware_rocker_container"
RESULT_TXT="result.txt"
RESULT_JSON_TARGET_PATH="${HOME}/aichallenge2023-racing/docker/evaluation/output/result.json"
TODAY=`date +"%Y%m%d%I%M%S"`
RESULT_TMP_JSON="result_${TODAY}.json" #"${HOME}/result_tmp.json"
GET_RESULT_LOOP_TIMES=180 # 30min
VAL1="-1" VAL2="-1" VAL3="-1" VAL4="false" VAL5="false" VAL6="false" VAL7="false"
for ((jj=0; jj<${GET_RESULT_LOOP_TIMES}; jj++));
do
if [ -e ${RESULT_JSON_TARGET_PATH} ]; then
mv ${RESULT_JSON_TARGET_PATH} ${RESULT_TMP_JSON}
# result
VAL1=`jq .rawLapTime ${RESULT_TMP_JSON}`
VAL2=`jq .distanceScore ${RESULT_TMP_JSON}`
VAL3=`jq .lapTime ${RESULT_TMP_JSON}`
VAL4=`jq .isLapCompleted ${RESULT_TMP_JSON}`
VAL5=`jq .isTimeout ${RESULT_TMP_JSON}`
VAL6=`jq .trackLimitsViolation ${RESULT_TMP_JSON} | tr -d '\n'`
VAL7=`jq .collisionViolation ${RESULT_TMP_JSON} | tr -d '\n'`
break
fi
# retry..
sleep 10
done
if [ ! -e ${RESULT_TXT} ]; then
echo -e "Player\trawLapTime\tdistanceScore\tlapTime\tisLapCompleted\tisTimeout\ttrackLimitsViolation\tcollisionViolation" > ${RESULT_TXT}
fi
TODAY=`date +"%Y%m%d%I%M%S"`
OWNER=`git remote -v | grep fetch | cut -d"/" -f4`
BRANCH=`git branch | cut -d" " -f 2`
echo -e "${TODAY}_${OWNER}_${BRANCH}\t${VAL1}\t${VAL2}\t${VAL3}\t${VAL4}\t${VAL5}\t${VAL6}\t${VAL7}" >> ${RESULT_TXT}
echo -e "${TODAY}_${OWNER}_${BRANCH}\t${VAL1}\t${VAL2}\t${VAL3}\t${VAL4}\t${VAL5}\t${VAL6}\t${VAL7}"
# finish..
bash stop.sh
}
function preparation(){
# stop current process
bash stop.sh
# リポジトリ設定など必要であれば実施(仮)
echo "do_nothing"
# 古いresult.jsonは削除する
RESULT_JSON_TARGET_PATH="${HOME}/aichallenge2023-racing/docker/evaluation/output/result.json"
if [ -e ${RESULT_JSON_TARGET_PATH} ]; then
rm ${RESULT_JSON_TARGET_PATH}
fi
}
function do_game(){
SLEEP_SEC=$1
preparation
run_autoware_awsim
get_result ${SLEEP_SEC}
}
function save_patch(){
_IS_SAVE_PATCH=$1
if [ "${_IS_SAVE_PATCH}" == "false" ]; then
return 0
fi
mkdir -p patch
TODAY=`date +"%Y%m%d%I%M%S"`
git diff > ./patch/${TODAY}.patch
}
# 引数に応じて処理を分岐
# 引数別の処理定義
IS_SAVE_PATCH="false"
while getopts "apl:s:" optKey; do
case "$optKey" in
a)
echo "-a option specified";
run_awsim;
exit 0
;;
p)
echo "-p option specified";
IS_SAVE_PATCH="true";
;;
l)
echo "-l = ${OPTARG}"
LOOP_TIMES=${OPTARG}
;;
s)
echo "-s = ${OPTARG}"
SLEEP_SEC=${OPTARG}
;;
esac
done
# main loop
echo "LOOP_TIMES: ${LOOP_TIMES}"
echo "SLEEP_SEC: ${SLEEP_SEC}"
save_patch ${IS_SAVE_PATCH}
for ((i=0; i<${LOOP_TIMES}; i++));
do
echo "----- LOOP: ${i} -----"
do_game ${SLEEP_SEC}
done
まとめ
- planning機能追加など試行錯誤の際は、なるべく評価を自動化して試行錯誤に集中できるようにすると良さそうな気がする
- 上記のために、シミュレータ+AWSIMを自動実行するスクリプトを作成
- 1回あたりの評価が楽になった事はもちろん、夜中にエージングテストする事も可能になった。何回かに1回の頻度で発生する不具合も事前に見つけやすくなったと思う。
- 動画キャプチャ、logの可視化、クラウド上での実行など拡張できそうな可能性を感じるが、そこまでするともはやジャッジサーバでありきりがなさそうなのでここまでにしておく。
つぶやき
(今回はオンライン評価環境が充実しているので、これを駆使できれば手元で自動実行したい需要って実はそこまで多くないのでは。。と思ったりもします)
参考