サッカーの FW ロボット(攻めるロボット)のプログラムを、ブラウザのシミュレーターで試します。シミュレーターで作ったプログラムは、そのまま実機で使います。記事の後半で、UnitV カメラあり・なしを同じ10か所から蹴り比べられます。
実機で1回試す手間 ― 書き込み・設置・走行・回収
実機で1回試すには、書き込む、コースに置く、走らせる、拾って直す、の4つの手間がかかります。シミュレーターは、書いてすぐ走らせられます。
シミュレーターで作ったプログラムを、実機で使う
シミュレーターで試して直したプログラムは、そのまま実機に書き込みます。実機用に書き直しません。
シミュレーターは、ボール・白線・向き・ゴールの値を、実機のセンサーと同じ形でプログラムに渡します。だから同じプログラムが、どちらでも同じように動きます。
カメラなしのプログラム ― ボールの後ろへ回り込む
int moveAngle = 0;
int moveSpeed = 0;
// 1. ボールの後ろへ回り込む
if (ballvalue != 99) {
int ball = ballvalue * 30; // ボールの方向(0〜330°)
if (ball > 180) ball = ball - 360; // −150〜180° に直す。右が+
int around = constrain(ball, -60, 60); // 横や後ろのボールは、外側へ最大60°回る
moveAngle = ball + around;
moveSpeed = 90;
}
// 2. 白線を踏んだら、内側へ逃げる
if (lineDetected) {
moveAngle = lineAngle;
moveSpeed = 100;
}
ボールを正面に置いてから押すために、ボールより外側へ回ります。進む方向は「ボールの方向 + 回り込む角度」で、回り込む角度は最大 60°です。
| ボールの方向 | 回り込む角度 | 進む方向 |
|---|---|---|
| 0°(正面) | 0° | 0° まっすぐ押す |
| 30° | 30° | 60° |
| 90°(右) | 60° | 150° 右うしろへ回る |
| 180°(うしろ) | 60° | 240° 左うしろへ回る |
このプログラムは、ロボットの向きを変えません。向きは heading 0、つまり相手ゴールの方向のままです。ボールはいつもまっすぐ前へ押されます。ゴールの正面から外れた位置では、ボールはゴールの横へ外れます。
カメラを足す ― UnitV でゴールの空いている側を向く
カメラなしのプログラムの最後に、次の11行を足します。上の部分は1文字も変えません。
// 3. カメラ:ゴールの空いている側へ、少しずつ向く
static float aim = 0; // 向きたい方向(heading の目盛り)
static unsigned long tPrev = 0;
float dt = min((millis() - tPrev) / 1000.0, 0.1); // 前のループからの秒数
tPrev = millis();
if (goalSeen) {
float want = constrain(heading + goalBearing, -45, 45);
float step = 36 * dt; // 1秒に36°まで
aim = aim + constrain(want - aim, -step, step);
}
KPMOTOR = KP * (aim - heading) * 100;
| 書き方 | やっていること |
|---|---|
| goalBearing | UnitV が見つけたゴールの色のかたまりのうち、いちばん大きいものの方位。キーパーがゴールの前にいると色が左右に分かれ、大きいほうが空いている側になる |
| heading + goalBearing | 空いている側の方向を、heading の目盛りに直した値 |
| dt | 前のループからの秒数。millis() で測るので、ループの速さが変わっても同じ速さで向きを変える |
| step = 36 * dt | 向きを変えるのは1秒に36°まで。一気に回ると、捕獲ゾーン(深さ2.5cm)からボールが外れる |
| KPMOTOR = KP * (aim - heading) * 100 | 向きを直す目標を、0 から aim に変える |
回り込みの部分はそのままです。体がゴールの空いている側を向いていれば、ボールの後ろへ回り込んだ時点で、ボールと空いている側が一直線に並びます。
実機では、UnitV から goalSeen と goalBearing を受け取る部分を、別に用意します。
FWロボット実験室 ― 同じ10か所から蹴り比べる
下の実験室は、上の2つのプログラムをそのまま動かしています。「10本勝負」は、決まった10か所からボールを蹴ります。位置はカメラあり・なしで同じです。
| カメラ | キーパー | 10本の結果 | 入った |
|---|
●が入った本数、○が外れた本数です。4つの組み合わせを同じ位置で比べられます。「別の位置にする」を押すと、位置と結果が入れかわります。
ロボット前のへこみが捕獲ゾーン
相手キーパー左右に動きながら、少しおくれてボールを追う
青い点線カメラが見つけた、ゴールの空いている側
実験室(シミュレーター)で、位置のセット 1〜20 を試した平均です。
| 相手キーパー | カメラなし | カメラあり |
|---|---|---|
| なし | 10本中 3.5 本 | 10本中 9.2 本 |
| あり | 10本中 2.9 本 | 10本中 6.0 本 |
同じ結果を、ボールの位置で分けます。
| ボールの位置 | カメラなし | カメラあり |
|---|---|---|
| ゴールの正面に近い(中央から 25cm 未満) | 88% | 82% |
| 横(中央から 25cm 以上) | 12% | 74% |
カメラが効くのは、横からのシュートです。正面に近い位置では、どちらもよく入ります。
シミュレーターにないもの ― 最後は実機で合わせる
シミュレーターは、現実を簡単にした模型です。フィールドの寸法・センサーの数と並び・ゴールの判定はルールどおりですが、次のものは再現しきれていません。
| 再現しきれないもの | 実機で起きること |
|---|---|
| タイヤのすべり | カーペットの毛足や汚れで、止まれる距離が変わる |
| 照明 | 会場の明かりで、UnitV が見るゴールの色が変わる |
| 電池の電圧 | 電池が減ると、同じ出力でも遅くなる |
| センサーの個体差 | ラインセンサー1個ずつ、白と緑の値がちがう |
この実験室は、ゴールが見やすいように、ボールを実物より軽く転がし、ジャイロのずれをなくしています。相手キーパーも、左右に動きながらボールを追うだけの簡単な動きです。
たとえば、白線を越えて外壁に当たるかどうか。教室で使っている、条件を細かく変えられるシミュレーターでは、白線に掛かる瞬間の速さが 0.7〜0.8 m/s をこえると外壁に当たりました。実機の境目は、走らせて止まる距離を測って決めます。シミュレーターで方針とおおよその値を決め、実機で合わせます。
ロボカップジュニア2027 に向けて、レスキュー(災害救助)とサッカーの2種目に取り組みます。プログラミングと電子工作の経験は問いません。