オムニホイールを3個付けたサッカーロボットの動かし方です。はじめは3個のうち2個のモーターだけを回し、6方向に動かしてボールを追いかけます。その先は、どの向きにも進める全方位です。全方位では、3個の車輪の速さを sin(三角関数)で決めます。式はひとつで、6方向はその特別な場合です。
オムニホイール3輪 ― 120°おきに3個
オムニホイールは、ふちに小さなローラーが並んだ車輪です。回る向きには力を出し、横にはすべります。だから、ななめに付けた車輪どうしがじゃまをしません。
この角度を取り付け角と呼びます。あとの式で使います。
まず6方向 ― 2個だけ回す
はじめは、3個のうち2個だけを回します。1個を止め、残りの2個をたがいに逆向きに回すと、ロボットはまっすぐ進みます。
| 進む方向 | 右前(60°) | うしろ(180°) | 左前(300°) |
|---|---|---|---|
| 前(0°) | 正転 | 止める | 逆転 |
| 右前(60°) | 止める | 正転 | 逆転 |
| 右うしろ(120°) | 逆転 | 正転 | 止める |
| うしろ(180°) | 逆転 | 止める | 正転 |
| 左うしろ(240°) | 止める | 逆転 | 正転 |
| 左前(300°) | 正転 | 逆転 | 止める |
止める車輪は、進みたい方向の線の上にある車輪です。前(0°)へ進むなら、真うしろ(180°)の車輪を止めます。
止める車輪の選び方が3通り、進む向きがそれぞれ2通り。あわせて6方向です。ボールが見えた方向にいちばん近い行を選べば、ロボットはボールへ近づきます。
6方向の限界 ― あいだの向きに進めない
6方向は 60°きざみです。ボールが 30°の方向にあっても、ロボットが選べるのは 0°か 60°。最大で 30°ずれた向きに進みます。
ずれた向きに進んでは選びなおすので、ロボットはジグザグに近づきます。ボールのうしろへ回りこむような、なめらかな動きもできません。
全方位へ ― 車輪の速さを sin で決める
全方位では、3個とも回します。それぞれの速さは、次の式で決まります。
| 車輪の速さ = 出力 × sin(取り付け角 − 進みたい方向) |
sin は、その車輪が進みたい方向にどれだけ役立つかを −1〜1 で返します。
| 取り付け角 − 進みたい方向 | sin | 車輪は |
|---|---|---|
| 90° | 1 | 全力で正転。車輪の向きと進みたい方向が同じ |
| 0° か 180° | 0 | 止める。回しても横向きの力にしかならない |
| 270° | −1 | 全力で逆転 |
30°の方向へ、出力 100 で進むときを計算します。
| 車輪 | 取り付け角 | sin | 速さ |
|---|---|---|---|
| 右前 | 60° | sin(60° − 30°) = +0.50 | +50 |
| うしろ | 180° | sin(180° − 30°) = +0.50 | +50 |
| 左前 | 300° | sin(300° − 30°) = −1.00 | −100 |
6方向では出せなかった 30°が、3個の速さの組み合わせで出ました。
実験室で動かす ― 方向を変えて、車輪の速さを見る
進みたい方向を動かすと、3個の車輪の速さがその場で変わります。
100 をこえた車輪があります。モーターはこれ以上出せないので、全部を同じ割合で小さくします。
さわるまでは、方向が自動でゆっくり回ります。円の中をドラッグするか、スライダーを動かすと止まります。青が正転、赤が逆転です。
見るところは4つです。
| やってみること | 見えること |
|---|---|
| 「全方位」で、方向をゆっくり1周させる | 3個の速さがなめらかに入れかわる |
| 「方向を決めておく」に切りかえる | 3輪は 60°きざみの6方向。必ずどれか1個が 0 になる |
| 「4輪」に切りかえる | 車輪が 45°・135°・225°・315° の4個になる。式は同じで、取り付け角が変わるだけ |
| 「回転」を動かす | 全部の車輪に同じ値が足される。進みながら、ロボットの向きを変えられる |
6方向は、式の特別な場合
6方向の表を、同じ式で計算しなおします。出力は 100 です。
| 進む方向 | 右前(60°) | うしろ(180°) | 左前(300°) |
|---|---|---|---|
| 前(0°) | +87 | 0(止める) | −87 |
| 右前(60°) | 0(止める) | +87 | −87 |
| 右うしろ(120°) | −87 | +87 | 0(止める) |
止める車輪は 0、残りの2個は +87 と −87。6方向の表と同じ形です。6方向は、sin がちょうど 0 になる向きだけを選んでいた、ということになります。
だから、プログラムを式に書きかえても、6方向へ進む向きは変わりません。あいだの向きが増えるだけです。
プログラム ― 関数ひとつで3輪ぶん
// 進みたい方向・出力・車輪の取り付け角から、車輪の速さを出す
int calcMotorSpeed(int angle, int power, int motorAngle) {
return sin(radians(motorAngle - angle)) * power;
}
// angle の方向へ、power の強さで進む
void move(int angle, int power) {
int val_A = calcMotorSpeed(angle, power, 60); // 右前
int val_B = calcMotorSpeed(angle, power, 180); // うしろ
int val_C = calcMotorSpeed(angle, power, 300); // 左前
motor_A.setSpeed(val_A);
motor_B.setSpeed(val_B);
motor_C.setSpeed(val_C);
}
| 書き方 | やっていること |
|---|---|
| radians() | 度をラジアンに直す。sin() は度のままでは計算できない |
| motorAngle - angle | 取り付け角 − 進みたい方向 |
| * power | −1〜1 を、モーターに渡す大きさに広げる |
| setSpeed() | モーターに速さを渡す。使っているモータードライバのライブラリの命令に合わせる |
ボールの方向が 30°なら move(30, 100) と書くだけです。方向ごとの場合分けが要りません。
動かないときに見るところ ― 症状から原因を引く
| 症状 | 原因 | 対処 |
|---|---|---|
| ねらった方向と真逆へ進む | 3個とも回る向きが逆 | 3個とも配線を入れかえる。または取り付け角に 180 を足す |
| 曲がりながら進む。またはその場で回る | 1個だけ回る向きが逆 | 1個ずつ正の値を渡し、図の青い矢印の向きに回るか見る |
| ねらった方向から 120°ずれる | モーターの A・B・C がずれている | motor_A が右前、motor_B がうしろ、motor_C が左前か確かめる |
| 方向を変えると、でたらめな向きへ進む | radians() を書いていない | sin(radians(…)) にする |
| まっすぐ進まず、少しずつ曲がる | モーターごとに力がちがう | ジャイロで向きを直す(別の回) |
ロボカップジュニア2027 に向けて、レスキュー(災害救助)とサッカーの2種目に取り組みます。プログラミングと電子工作の経験は問いません。