SWEST24 9/2(金) 12:30～13:40 セッションs4c
https://swest.toppers.jp/SWEST24/program/s4c.html#s4

WEBブラウザ上で動作する
ETロボコンシミュレータの仕組みについて
ETロボコン東京地区 実⾏委員
新 吉⾼（あたらし よしたか）1

１.１ 講演者紹介• 2015年よりETロボコン実⾏委員会に東京地区実⾏委員として参加• 2017年東京地区実⾏副委員⻑を経て、2018年より東京地区実⾏委員⻑
• 2020年⼤会で⽤いられたETロボコンシミュレータ(Unity)の設計・実装を担当• 本業は某企業で組込みソフトからクラウド上でのデータ分析まで薄く広く対応するエンジニア兼マネージャ。
• 技術⼠(情報⼯学部⾨)ETロボコン実⾏委員会 2022

東京地区⼤会懇親会後の集合写真
2

１.２ ETロボコンとはEmbedded Technology Software Design Robot Contestの通称で、LEGO社のLEGO Mindstormsを使⽤した⾃律型ライント
レースロボットの設計とタイムを競うコンテストです。

総合部⾨モデル部⾨

システム分析、ソフトウェア設計モデル

ETロボコン実⾏委員会 2022

＋競技部⾨⾛⾏競技による性能

3

1.3 コロナ禍でのETロボコン• ETロボコン実⾏委員会はコロナ禍のため、2020年度の⼤会をシミュレータ⼤会とすると決定• TOPPERS/箱庭WGが組込みCPUシミュレータAthrillを開発• 発表者は3Dゲーム開発環境として有名なUnityを⽤いて、Athrillと連携可能なETロボコンシミュレータを開発• 2020~2021年の⼤会はシミュレータのみで実施• 2022年の⼤会は実機（アドバンストクラス、プライマリークラス）とシミュレータ（エントリークラス）の併⽤となった
ETロボコン実⾏委員会 20224

1.4 ⼤会版ETロボコンシミュレータの構成
参加チーム開発 ⾛⾏体制御ソフトウェア
プログラミング⾔語︓C/C++

新が開発した部分
ETロボコンシミュレータ(参加者限定)棚橋先⽣の開発

etrobo環境
TOPPERSの成果物

EV3RT/ASP3

箱庭WGの成果物

単体ロボット向け
シミュレータ(⼀般公開)

エミュレータ向け移植版箱庭WGの成果物＋⼟樋さんの改善

Athrill

CPU エミュレータ

同期・通信(UDPのみ)
ETロボコンの独⾃拡張あり

https://github.com/ETrobocon/etrobo
ETロボコン実⾏委員会 2022

同期・通信(UDP, ROS …)
箱庭WGの独⾃拡張あり

参照： https://toppers.github.io/hakoniwa/prototypes/single-robot/5

1.5 ETロボコン2021 CS⼤会競技優勝⾛⾏
https://youtu.be/lh1g9Nbq-aU

ETロボコン実⾏委員会 20226

1.6 関係者の要求とその評価• ETロボコン実⾏委員会の要求︓ 学びの歩みを⽌めない︕– シミュレータ⼤会を実施すること。 → OK
– 箱庭WGの成果物を活⽤すること。 → OK
– ライントレースのみの簡易なものでも⼗分。 → 難所攻略も可能なレベルに– 競技判定は⽬視でもよい。 → ⾃動判定可能• 箱庭WGの要求︓ 成果物を多くの参加者にアピールしたい︕– Athrillと単体ロボットシミュレータを⼤会で利⽤すること。→ Athrillのみ利⽤– 箱庭WGにHackEV⾛⾏体の3Dモデルを提供すること。 → OK
– ⼗分な開発時間を⽤意することはできない。→ ⼟樋さんが開発を⽀援• 発表者の狙い︓ リアル⼤会の雰囲気を再現したい︕– エントリー、プライマリー、アドバンストの3クラスをすべてサポートする。 → OK
– ⾛⾏体の動作をすべてAPIで制御できるようにする。→ ⾳と画⾯以外OK– Unityの物理エンジンで作り切る。 → OK
ETロボコン実⾏委員会 20227

1.7 ETロボコン 2022 プロモーションビデオ
https://youtu.be/v8O5J65B4uA

ETロボコン実⾏委員会 20228

1.8 ETロボコンシミュレータ評価環境
https://github.com/ETrobocon/etrobo

サンプルコースのみ走行可能なシミュレータを一般公開している。
誰でも自由にインストール可能。
ワンコマンドでインストールできるが、一度失敗すると結構ハマる。
ETロボコン実⾏委員会 20229

2.1 ETロボコンシミュレータの課題と解決案
多くの制約の中で開発したため、様々な課題が残っている。
ETロボコンシミュレータの課題

解決案

複数OS対応によりインストーラが複雑化し、 WebGLによるOS⾮依存化、インバージョンアップ毎に不具合報告がある
ストールレス環境の実現（ruby、M1 Mac、WSL関係が多い)
参加者メリットの維持のため、シミュレータのソースコードを公開できない

ソースコードを公開可能なバージョンを別に開発する。

マイコンシミュレータAthrillとのUDP通信周 Athrillの代わりに軽量なスクリプト期を短くできず、倒⽴振⼦制御の実現が難 ⾔語を⽤いる（この場合、EV3⽤しいコード⽣成のメリットは無くなる）
JSONファイルでコースをカスタマイズできるものの、難所の配置の⾃由度が低い
ETロボコン実⾏委員会 2022

スクリプト⾔語で⾃由に配置できるようする
10

2.2 Web版ETロボコンシミュレータを作ってみた••

WebGLによるOS⾮依存化、インストールレス環境の実現
Athrillの代わりに軽量なスクリプト⾔語(MiniScript)を⽤いる
https://webglsim.etrobo.jp

API⼀覧

MiniScript仕様

Aceエディタ
(MiniScript⽤)
シミュレータ操作

ETロボコン実⾏委員会 2022

スクリプト実⾏11

2.3 WEB版ETロボコンシミュレータの位置付け
⼤会⽤ETロボコンシミュレータのコードを⼀部流⽤しているが、WebGLでビルド・実⾏できるようにかなり書き換えている。

ETロボコン実⾏委員会 202212

練習1: HackEV(ロボット）を動かそう① Web版ETロボコンシミュレータをブラウザで起動する。
② エディタに下記プログラムをコピペする。
ev3_motor_set_power_left 50
ev3_motor_set_power_right 50
wait 10③ シミュレータ部分をマウスでクリックし、Vキーを押す。
④ Run Scriptボタンを押す。

ETロボコン実⾏委員会 202213

ヒント1︓ FPSが20以下の場合(遅いPCの場合）① HackEV(Simple)を選択する。
② Resetを押す。

簡易モデルに切り替わります。

ETロボコン実⾏委員会 202214

実習1: HackEV(ロボット）を⾃由に動かそう① シミュレータ上のResetを押す。
② エディタ上でev3_motor_set_power_left、ev3_motor_set_power_right、 waitを使って、⾃由にプログラムを書く。for ⽂を使って動きを繰り返してみるもよし。
for i in range(0,10)
ev3_motor_set_power_left 50
ev3_motor_set_power_right 50
wait 2
ev3_motor_set_power_left -50
ev3_motor_set_power_right 50
wait 0.3
end for③ シミュレータ部分をマウスでクリックし、Vキーを押す。
④ Run Scriptボタンを押す。
この⽅法でゲート１と２を通過し、ゴールまで⾛らせてみよう。
ETロボコン実⾏委員会 202215

2.4 WebGLによる開発••••

UnityのWebGLでの開発は通常の開発よりも⼤変
C#のソースコードを変更するとビルドに数分かかるUnityエディタ上で動いたとしても、ちょっとしたことでブラウザ上で動かなくなるgithubに少しづつコミットしながら動作確認をする必要があった

ETロボコン実⾏委員会 2022

16

2.5 WebGLでのビルドと実⾏ビルドが成功すると index.html を含むファイル群が⽣成される。

index.html をHTTP経由でアクセスする必要がある。例えば、python -m http.server を⽤いることでローカルPC上での動作確認ができる。
ETロボコン実⾏委員会 2022

17

2.6 Azure Static Web Apps へのデプロイ
ビルド結果をgithubにコミットすると、Azure Static Web Appsが⾃動的にデプロイしてくれるETロボコン実⾏委員会 202218

2.7 メトリックの確認
定常的に、１⽇当たり200~400MB(4~8回)のアクセスがある

ETロボコン実⾏委員会 2022

19

練習2: HackEV(ロボット）でライントレース① Web版ETロボコンシミュレータをブラウザで起動する。
② エディタに下記プログラムをコピペする。
// P制御で⾛る。
v=50 // まっすぐの時の速度指令値
for i in range(0,10000) // 10000周期分動かす。
ref=ev3_color_sensor_get_reflect // カラーセンサから反射光の強さを取得する。
p=(ref-18)*2 // ⽬標値18からの差分に係数2をかける。
ev3_motor_set_power_left (v-p) // 右エッジの場合、⽬標値より暗い場合は右に曲がるように制御する。
ev3_motor_set_power_right (v+p) // 右エッジの場合、⽬標値より暗い場合は右に曲がるように制御する。
yield // 次の制御周期(5ms)まで待つ
end for③ シミュレータ部分をマウスでクリックし、Vキーを押す。
④ Run Scriptボタンを押す。

⿊いラインの右側に沿って⾛っている。
ETロボコン実⾏委員会 202220ヒント2︓ センサ値の確認⽅法① ブラウザでF12キーを押す(IE/Edgeの場合)② アプリケーション＞ストレージ＞セッションストレージの中のURLをクリックする。
③ スクリプト実⾏中は、MiniScriptのAPIによって取得可能な値を観測できる。

ETロボコン実⾏委員会 202221

実習2: HackEV(ロボット）で左エッジライントレース① Web版ETロボコンシミュレータをブラウザで起動する。
② 練習2のプログラムを改造して、左エッジをライントレースするように変更する。
③ シミュレータ部分をマウスでクリックし、Vキーを押す。
④ Run Scriptボタンを押す。

コース形状が複雑なので、途中でライントレースに失敗するかも。
こっちに⾏けば成功

ETロボコン実⾏委員会 2022

ゴールまで完⾛するにはどうすればよいか︖

22

2.8 MiniScript
ロボットを制御するためのプログラミング⾔語を検討した・インタプリタ型で簡単に実⾏できる・C#で実装されている・Unity上のオブジェクトを容易に操作できる・関数拡張が容易であるという利点から、MiniScriptを採⽤した。

ETロボコン実⾏委員会 2022

https://miniscript.org

23

2.9 MiniScriptの組み込み
UnityにMiniScript-csを取り込み、MiniScript制御⽤オブジェクトを追加

ETロボコン実⾏委員会 202224

2.10 MiniScriptの関数拡張
miniscriptからセッションストレージを経由し、Unity上のロボットを制御するための関数をC#側に追加
static void AddIntrinsics(Dictionary<string, int> sensorMS, Dictionary<string, int> actuatorMS){
if (intrinsicsAdded) return;Get系関数Set系関数

intrinsicsAdded = true;
Intrinsic f;
foreach (var key in sensorMS.Keys) {f = Intrinsic.Create(key);f.code = (context, partialResult) => {var rs = context.interpreter.hostData as ExecMS;
if (rs.isRunning()){
var hv = rs.hackev;
return new Intrinsic.Result(hv.sensorMS[key]);}
else{
return Intrinsic.Result.Null;}};}// 以下略
ETロボコン実⾏委員会 202225

2.11 WEBエディタ Ace
JavaScript+CSSで提供されるWEBブラウザ上で動作するテキストエディタ
https://ace.c9.io

Unityとの連携は、RunCodeボタンを押したときにAceエディタ上の MiniScript
コード を送信するJavaScriptを記述することで実現している
var editor = ace.edit("editor");editor.setTheme("ace/theme/twilight");
editor.session.setMode("ace/mode/miniscript");function RunCode() {code = editor.getValue();
unityInstance.SendMessage("MiniScript", "RunScript", code);}
ETロボコン実⾏委員会 202226

練習3: EV3way(倒⽴振⼦ロボット）を動かす① 上のメニューでEV3Wayを選択し、リセットする。
② エディタに下記プログラムをコピペする。
speed=40 //前進速度
str=0 //旋回速度
balance_init // 倒⽴振⼦初期化
for i in range(0,3000)// 倒⽴振⼦制御
balance_control speed,str, ev3_gyro_sensor_get_rate,0,ev3_motor_get_counts_left,ev3_motor_get_counts_rightev3_motor_set_power_left balance_pwm_l
ev3_motor_set_power_right balance_pwm_r
yield
end for③ シミュレータ部分をマウスでクリックし、Vキーを押す。
④ Run Scriptボタンを押す。

ETロボコン実⾏委員会 2022

27

ヒント３︓ 倒⽴振⼦とはETロボコンで⻑く愛されてきた倒⽴振⼦。
タイヤの回転数と回転速度、⾞体の⾓度と⾓速度を⼊⼒として、倒⽴を維持するようにモータの制御値を計算する。
今回は2017年のEV3Wayのモデル(塚本さん作)を利⽤し、下記APIを提供している。頑張ればMiniScriptを使って⾃分で実装することもできる。
• balance_init• balance_control• balance_pwm_l• balance_pwm_r
⼤本のロジック︓ NXTway-GS(2輪型倒⽴振⼦ロボット) C API
http://lejos-osek.sourceforge.net/jp/nxtway_gs.htm
参考にしたパラメータ︓ EV3way ETロボコンで使⽤している倒⽴振⼦APIパラメーターの再計算⼿順
https://qiita.com/pulmaster2/items/08edce1ab097539b2deb
ETロボコン実⾏委員会 202228

実習3: EV3way(倒⽴振⼦ロボット）でライントレース① 上のメニューでEV3Wayを選択し、リセットする。
② 練習3と、練習2or実習2のプログラム参考にして右or左エッジをライントレースするように変更する。
③ シミュレータ部分をマウスでクリックし、Vキーを押す。
④ Run Scriptボタンを押す。
ライントレースだけで、右エッジを30秒台、左エッジを40秒台でゴールまで⾛れればまぁまぁ速い。

ETロボコン実⾏委員会 202229

2.12 MiniScript+EV3 APIだけで倒⽴振⼦を実現
愚直に倒⽴振⼦ライブラリのC実装をMiniScriptに移植すればよい。
https://qiita.com/YoshitakaAtarashi/items/2764c840dd3efce4f060
balancer={}// ローパスフィルタ係数(左右車輪の平均回転角度用)
balancer.A_D = 0.8// ローパスフィルタ係数(左右車輪の目標平均回転角度用)
balancer.A_R = 0.996// 状態フィードバック係数// K_F[0]: 車輪回転角度係数// K_F[1]: 車体傾斜角度係数// K_F[2]: 車輪回転角速度係数// K_F[3]: 車体傾斜角速度係数
balancer.K_F = [ -0.870303, -31.9978, -1.1566, -2.78873 ]// サーボ制御用積分フィードバック係数
balancer.K_I = -0.44721// 車体目標旋回角速度係数
balancer.K_PHIDOT = 25.0 * 2.5// モータ目標回転角速度係数
balancer.K_THETADOT = 7.5// 制御周期[s]balancer.EXEC_PERIOD = 0.005// コマンド最大値
balancer.CMD_MAX = 100.0// 初期化
balancer.ud_err_theta = 0.0
balancer.ud_theta_ref = 0.0
balancer.ud_thetadot_cmd_lpf = 0.0
balancer.ud_psi = 0.0
balancer.ud_theta_lpf = 0.0
balancer.DEG2RAD=(pi * 2) / 360
balancer.ret_pwm_r=0
balancer.ret_pwm_l=0

ETロボコン実⾏委員会 2022

balancer.control=function(args_cmd_forward, args_cmd_turn, args_gyro, args_gyro_offset,
args_theta_m_l, args_theta_m_r)
tmp_thetadot_cmd_lpf = (((args_cmd_forward / balancer.CMD_MAX) * balancer.K_THETADOT) *(1.0 - balancer.A_R)) + (balancer.A_R * balancer.ud_thetadot_cmd_lpf)
tmp_theta = (((balancer.DEG2RAD * args_theta_m_l) + balancer.ud_psi) + ((balancer.DEG2RAD* args_theta_m_r) + balancer.ud_psi)) * 0.5
tmp_theta_lpf = ((1.0 - balancer.A_D) * tmp_theta) + (balancer.A_D *balancer.ud_theta_lpf)
tmp_psidot = (args_gyro - args_gyro_offset) * balancer.DEG2RAD
tmp = [ balancer.ud_theta_ref, 0.0, tmp_thetadot_cmd_lpf, 0.0 ]tmp_theta_0= [ tmp_theta, balancer.ud_psi, (tmp_theta_lpf - balancer.ud_theta_lpf) /balancer.EXEC_PERIOD, tmp_psidot ]tmp_pwm_r_limiter = 0.0
for tmp_0 in range(0,3)
tmp_pwm_r_limiter = tmp_pwm_r_limiter + (tmp[tmp_0] - tmp_theta_0[tmp_0]) *balancer.K_F[tmp_0]
end for
tmp_pwm_r_limiter =(tmp_pwm_r_limiter*20 + (balancer.K_I * balancer.ud_err_theta)*2)
tmp_pwm_turn = (args_cmd_turn / balancer.CMD_MAX) * balancer.K_PHIDOT
tmp_pwm_l_limiter = tmp_pwm_r_limiter + tmp_pwm_turnbalancer.ret_pwm_l = tmp_pwm_l_limiter
tmp_pwm_r_limiter = tmp_pwm_r_limiter-tmp_pwm_turnbalancer.ret_pwm_r = tmp_pwm_r_limiterbalancer.ud_err_theta = ((balancer.ud_theta_ref - tmp_theta) * balancer.EXEC_PERIOD)+balancer.ud_err_thetabalancer.ud_theta_ref = (balancer.EXEC_PERIOD * tmp_thetadot_cmd_lpf) +balancer.ud_theta_refbalancer.ud_thetadot_cmd_lpf = tmp_thetadot_cmd_lpf
balancer.ud_psi = (balancer.EXEC_PERIOD * tmp_psidot) + balancer.ud_psibalancer.ud_theta_lpf = tmp_theta_lpf
end function
speed=40 //前進速度
str=0 //旋回速度
for i in range(0,10000)// 倒立振子制御
balancer.control(speed,str,ev3_gyro_sensor_get_rate,0,ev3_motor_get_counts_left,ev3_motor_get_counts_right)
ev3_motor_set_power_left balancer.ret_pwm_l
ev3_motor_set_power_right balancer.ret_pwm_r
yield
end for30

3. さいごに••多くのETロボコン実⾏委員およびTOPPERS/箱庭WGの努⼒によって、2020年~21年のリモートによるETロボコン⼤会は無事終了した。リアル⼤会さながらの興奮を味わうことができたと評判は上々であった。
WEB版ETロボコンシミュレータは⼤会向けと⽐べると機能が限定されているが、インストールレスで簡単に動作させることができるため、様々な応⽤が考えられる。

新のシミュレータ解説動画

ETロボコン実⾏委員会 2022

31

A. 参考(Qiita)
https://qiita.com/YoshitakaAtarashi/items/877d1a0cc5ba94a39755
https://qiita.com/YoshitakaAtarashi/items/4e9985f9751260cbe20e

ETロボコン実⾏委員会 2022

32

終わり33