Rootをプログラミングする時に、最終的な目標はルンバみたい動きをさせることですよね。
どういうプログラムを使えばルンバの動きに近づけられるのか考えてみました。
初期のルンバのプログラムを調べてみた
ルンバは実は自動走行型の地雷探査機を元に開発されました。
自動走行型地雷探査機に求められる能力は大きく分けるとこの3つです。
- 地雷があったら確実に感知する
- 指定範囲をもれなく探査する
- 障害物を避ける
1.はセンサーの性能の問題なので、今回はあまり触れないでおきます。
2.3.の性能はプログラムによって大きく変わります。
現代のルンバは位置情報をマッピングしたり、ほぼペットと同じレベルで室内を動き回ります。
Rootにはさすがにそこまでの機能は搭載されていません。
なので、ルンバの初期モデルのプログラムを調べてみましょう。
ルンバは掃除している部屋の地図を作成しない。その代わりに「らせん状に掃除する」「壁伝いに掃除する」「何かにぶつかったら角度を変えてランダムウォークする」など、いくつかの単純なヒューリスティックスで動作している。『引用元:ルンバ(掃除機)|wikipedia』
ヒューリスティクスとは、必ずしも正しい答えを導けるとは限らないが、ある程度のレベルで正解に近い解を得ることができる方法である。『引用元:ヒューリスティクス|wikipedia』
wikipedia先生によれば、ランダムに動くことで掃除を行っているようです。
ランダムと言っても本当に何も考えていないランダムというわけではないようです。
今まで積み上げられたデータを基にしたランダムだそうです。(これをランダムというのかは不明)
ルンバにもランダムが使われているということが分かったので、さっそくRootでプログラミングしてみましょう!
Rootでランダムを使ったプログラム
ランダムな数字を作成するブロックと言えばこれです。
「ランダムinteger 0から100へ」ブロック
このブロックは0~100の数字をランダムで生成するブロックです。
生成する数字は変更することができます。
この数字の部分をクリックすれば、範囲を変えることができます。
また、integerの部分をクリックすると、生成する数字を整数だけにするか少数も含めるかを変えられます。
このブロックを使ってランダムな動きを作っていきます。
Rootの動きをランダム化する方法はいくつああります。
まずは僕が考えたRootの動きをランダム化する方法です。
- 実行する確率をランダム化
- 実行する間隔をランダム化
- 回転する角度をランダム化
それぞれ見ていきましょう。
1.実行する確率をランダム化
実行するプログラムの内容は一定にして、それが実行される確率をランダムにする方法です。
もし~~の部分がランダムな動きを作り出しています。
中身の部分を見ていきましょう。
ここで使っているのは、もし、比較演算、ランダムの3つです。
一応、比較演算、もしの使い方を説明しておきます。
知ってる人は飛ばしてOK。
まず、ランダムブロックを比較演算の数字の部分にはめ込みます。
そのあとに、「=→≧」、「0→51」に変えます。
そうするとこういう式が出来上がります。
この式は、「ランダムな数字が51以上」という意味を持ちます。
この関係式と「もし~なら」ブロックを組み合わせます。
するとこうなります。
このプログラムは、「もしランダムな数字が51以上の場合」という意味になります。
そして、下にある「あてはまらないとき」と組み合わせることで1/2の確率を作り出しています。
このランダム化プログラムを文章で説明するとこうなります。
ランダムに1~100の数字を生成するよ。
このランダムの数字が51以上の時に、右に90度回転を実行して。
あてはまらないとき(50以下の時)は左に90度回転を実行して。
回りくどい表現ですが、こう記述しないとコンピュータは理解してくれません。
これで、実行する内容は変えずに、実行する確率をランダム化することができます。
もちろん、場合分けの数を変えれば3択以上にもできます。
2.実行する間隔をランダム化
次は実行する間隔をランダム化する方法です。
Rootが「直進して時計回りに回転する」を繰り返すプログラムでも、実行する間隔がランダムなら動きはランダムになります。
このプログラムでは、2つのプログラムの間隔をランダムにしています。
直進→(ランダム)→回転
回転→(ランダム)→直進
この2つの間隔をランダムにすることで、
どれくらいの時間直進するか
どれくらいの時間回転するか(どれくらいの角度曲がるか)
をランダムにしています。
これで、ランダムな動きを作り出すことができます。
3.回転する角度をランダム化
このプログラムではダイレクトに回転する角度をランダムにします。
曲がる角度をランダムにすれば、動きがランダムになるのは直感的にわかりますよね!
ただ、どういう風にランダムにするかでより効率のいい?ランダムを作ることができます。
僕の場合はRootがダラダラと回転しているのを待つのが性に合わないので、ランダムの角度を「-180~180度」にしています。
(※右回りにー180度=左回りに180度)
こうすることで、回転し続ける時間をできるだけ短くするようにしています。
右回りに350度よりも左回りに10度の方が速いですからね!
Rootでルンバに似たプログラムを作る方法
今回はルンバに似た動きをするプログラムを作るために、3.回転する角度をランダム化を使っていきます。
ルンバは壁に衝突した時に進む向きを変えるので、「バンパーがおされたとき」ブロックを使います。
バンパーが押された時、向きをランダムに変えるようにします。
「色をスキャンしたとき」ブロックは、外に出ていかないように壁を作ってるブロックです。
こういった壁を準備できる人はこのプログラムは必要ありません。
壁を準備できない人は黒ペンで周りを囲んで、Rootが外に出ていかないようにしましょう!
まとめ
どうでしたか?
最後のプログラムは、理論上どんな広さの部屋でも障害物がどんな配置でも掃除を完了することができます。
ただ、ランダムなのでどれくらいの時間がかかるかは運次第・・・
今のところこのプログラムくらいしかどの部屋でも完全に掃除が可能なものはありません。(僕の頭で思いつく限りでは)
もしあればコメント欄で教えてください!