MATLAB/SimulinkでETロボコンに出場する:調整が簡単なアーキテクチャ

ETロボコンという競技は、設計はもちろん大事ですが、実際にロボットでコースを走らなきゃいけないので、調整に時間が掛かります。 ここをどうやって簡単にするかも、最終的な仕上がりを決める重要ポイントの1つでして。 

これまで、いろんなモデルを見ていましたが、調整パラメータは、プログラムのソースコードに埋め込まれ、一緒にコンパイルされることが多かったです。 ところが、これが結構、手間がかかる手順でして。 ソースコード上のパラメタを書き換え、コンパイルし、ロボットとケーブルで繋いで、プログラムを転送して、プログラムを起動して、コースの調整したい場所まで歩いていって、実験する。 これを延々と繰り返すわけです。 たぶん数百回レベルの数で。

たとえば1回に掛かる時間を2分短縮すると、100回で200分、500回で1000分ほど時間が節約になるし、コースのまわりを歩き回る労力も減ります。1000分といえば、1日に2時間使って調整したとしたら、8日間は節約できます。

今回の巨匠チームは、調整方法に2つの方式を取り入れました。


1.静的シナリオ
  ソースコードと一緒に、調整パラメタを書いたファイルを用意し、コンパイル時に取り込まれる方式

2.動的シナリオ
  EXCELで調整パラメタを書き、それをツールを使って無線通信により、走行体プログラムに送り込む方式


静的シナリオは、プログラムと一体になっているので、いつ何時でも、安定してプログラムが動く利点があります。 対して動的シナリオは、動作中のプログラムに無線で送り込むので、走行体が遠く離れた場所にあってもすぐに書き換えられる利点があります。 ただ、大会本番ではBluetoothの電波がうまく届かないことがあり、これだけに頼ると、動的シナリオが転送できないので走れません! という事態になりかねません。
度重なる調整は動的シナリオでやり、固まってきたら静的シナリオにして、プログラムに埋め込むという手順が一番良さそうですが、巨匠チームは、大会ではどうだったのでしょうねぇ。


Scenario_2

全体の構成はこんな感じになります。競技者はEXCELのシートにシナリオを書きます。 コマンダーという通信アプリで、シートの1つを選んでBluetoothで送信します。 EV3内部では、今回開発したプログラムがBluetooth受信で、シナリオ1行1行を受け取りますが、動的シナリオのRECモードのときだけ動的シナリオバッファに溜めます。
シナリオ管理者は、動作モードが静的シナリオか動的シナリオかに応じて、どちらかのシナリオグループか順位シナリオを取り出して送り出します。 シナリオグループというのは、一連のシナリオを更に複数まとめあげる役割をしています。

最近のETロボコンでは、こういう動的なシナリオ編集システムを同時に開発しているチームを時々見かけます。 最初に見かけたのは、H社の研究所の人達が出てきたときだったでしょうかね。 よくもまあ、こんなに作り込んだもんだ、と関心しました。 EXCELのシナリオを書いてコマンダーで送る人、 走行体をコース上でセットする人、の二手に分かれて作業ができるので、コース回りの移動をしなくても済むし、トライ&エラーのターンアラウンドがとても短くなります。

次回は、これが実際に動かせるファイル一式をもってきましょう。 実際にやってみて実感するのが一番ですからね。

| | コメント (0)

MATLAB/SimulinkでETロボコンに出場する:拡張性が高いアーキテクチャ

ETロボコンって、設計して実装してテストすると、大概、途中で機能が足りないことが分かるもんです。このA方式より、こんなB方式のほうがいいんじゃね? なんてね。 なので、途中の機能アップの拡張性がないと、あとでグチャグチャに。 そこで、どこの段階が一番手が入るかというと、コースを区間に区切って、条件によって制御を切り替えて、次の区間に移って、の部分の条件(ジャッジ)と制御(アクション)  これについては、むかしむかしJudge & Actionアーキテクチャで解決したことがあるので、いまでもそれを流用してます。

Jaarch

図解するとこうなります。 

1. 茶色のシナリオ管理は「この条件が成立したら、この制御をやる」という1つのシナリオを取り出して、 青いジャッジグループに「こんな条件は成立したか?」 と発信します。誰となく指名することなしに。

2. そうすると、青いジャッジAからジャッジCの全員が、そのメッセージを受け取るわけですが、自分の知らない条件を判定しろと言われても無理。 そういうときは無視します。

3. ところが、ジャッジBは「この判定なら俺の役目だから判定してやろう」 と違う動きをして、もし、判定結果がOKなら、ジャッジグループに1個だけある、条件成立の旗を立てます。1個しかないですからね。

4. シナリオ管理は、条件成立の旗を見てて、なにも立たなければ、次のタイミングでもう一度同じことを繰り返します。 もし条件成立の旗が立っていたら、それを下ろしておいて、今度はアクショングループに「こんな制御して」と発信します。

5. アクションDからアクションFは、それぞれ同じメッセージを受け取るわけですが、「おれ、そんなこと言われても知らない」という人もいれば、「それできるわ、やるね!」という人もいます。 普通、それは一人だけ。

6. そして制御が実行され、また次のタイミングになって、シナリオ管理は次のシナリオを取り出して、同じことを続けるわけです。


さて、ここで新しく条件判定を追加したいとします。ジャッジGはその他のジャッジと同じ形をしているんですが、誰も判定してくれない新しい条件判定ができます。 これをジャッジグループに追加します。 あとは何も構造を変更することなしに機能拡張が完了。 これがジャッジ & アクションアーキテクチャです。 水中ロボットのハコフグちゃんにも、ETロボコンで作った仕組みそのままを移植して、水中ロボット用のジャッジとアクションに入れ替えました。 また、シナリオを図で作成できる仕組みも、中身を入れ替えて再利用。 意外と、いろんな場面で使える仕組みです。

それで、今回の巨匠チームにも、もちろん、このアーキテクチャを使いました。それをSimulinkで作るにはどうするか?ということです。 しかし、もともと、BricRoboで作るように考えた構造なので、Simulinkでも特に難しくもなく。

Ja2

前回も出てきた心臓部の部分、ここに3色で囲んだ部分が、説明のシナリオ管理、ジャッジグループ、アクショングループに相当します。

Judge

ジャッジグループの中身はこんな感じになってます。1つの線が分かれて複数につながる、という書き方はデーターフロー的な設計の良いところです。BricRoboも同じですけどね。シミュレーションができないだけで。

Action

アクショングループもこんな感じになってます。ただ、ここでは実際の制御をするわけでなく、シャシー側に用意されている制御ブロックに対して、さらに制御命令を出す、という構造になってますが、アーキテクチャ的には一緒です。

いつも、テキスト言語を先に書き出して、大きな構造を見つけられなくて、困っている人も多いんじゃないですかね。図形言語は形が綺麗だと、大抵、筋がいいので、慣れると楽です。


MATLAB/SimulinkでETロボコンに出場する:はじめに
MATLAB/SimulinkでETロボコンに出場する:Unityと繋ぐ
MATLAB/SimulinkでETロボコンに出場する:シナリオで振る舞う心臓部
MATLAB/SimulinkでETロボコンに出場する:拡張性が高いアーキテクチャ

| | コメント (0)

MATLAB/SimulinkでETロボコンに出場する:シナリオで振る舞う心臓部

大体ですねぇ、ETロボコンに出場するシステムを見ていると、多かれ少なかれ、走るコースを区間に分けたり、難所を渡っていくシーンを分割したりして、分割した1つの区間について、どのようなアクションを実施したり、どんなジャッジが成立したら、次の区間へ遷移するか、という仕組みが入っているわけです。 そりゃモデルシート見ると明らか。 昔、水中ロボコンに出場したハコフグちゃんにも、2010年あたりにETロボコン用に開発した仕組みが移植され、それでシナリオ通りにロボットを動かしていました。 

Driver

もちろん、この巨匠チームのMATLAB/Simulinkモデルにも、その部分があります。 いろんなことができるのは、この心臓部があるからでして。それが、ここです。 大きく4つの部分に分かれています。 左下の肌色の部分、これがステートマシン図です。 はい、図そのもの。 MATLAB/Simulinkとこれまで言ってますが、Stateflowという状態遷移のブロックが作れるアドインも一緒に使ってます。 Simulinkは四角いブロックの左からデータが入ってきて、ブロックの中で演算して、右側から出ていく、というデータフロー的な設計しかできません。 状態を表すところはStateflowのChartというブロックを使って設計します。中にはステートマシン図が入っていて、Chartの外から入ってきた信号を値として参照したりイベントとして扱ったりし、それによってい状態遷移を起こしたり演算したりして、その過程でデータが変化したりイベントが発生したりして、Chartの外に信号として出ていきます。 この入出力の信号とSimulinkのブロックを繋げて、Simulinkブロックの振る舞いを変えていくという方式。 なるほどねぇ。 みんなステートマシン図って書くことはあるけど、 その振る舞いをどうやって他と結びつけるか、まではあまり考えていないと思うんですよ。 いい勉強になるわ。

Chart

このChartを開くと、さらに2つのChartが入ってます。左側がロボット全体の状態を制御します。右側は実行するシナリオを1つ1つ駆動します。 この2つのChartが同時に並列動作していて、左側で人間がボタン操作すると走行を開始したり止めたり、シナリををBluetoothで受信したり、いろいろ操作します。 その状態遷移の過程でイベントが発生し、右側のChartに伝えられ、シナリオ実行を開始したり止めたりします。 このステートマシン図、そのまま動くのがStateflowのいいところ。 シミュレーション中に開くと、現在アクティブな状態は青線で囲まれて、遷移している様子が見れます。 すげー。 ステートマシン図って、書いたことはあっても、実際に動いている様子って、見たことある人は少ないでしょ。 見たことないと、このステートマシン図みても、タダの図であって、実際に動くようにするには、C言語のSwitch文とかで実装してやらないとダメとか思ってるでしょ。 ざんね~ん。このまま動きます。

じゃ、シミュレーション中に動いているのを録画してみましょう。分かりやすくするために、Chartのアニメーション速度は低速にしてあります。左側はステートマシン図、右上はUnity、右下はダッシュボード。シミュレーションを開始すると左側に青い囲みが現れて、状態遷移が起こっているのがわかります。シナリオが進むと右上のEV3の尻尾が降りてきます。 ここで動かないようにロックしているのをほどいて(尻尾が降りてくるまで手で抑えることができないので) タッチセンサーのボタンを押すと、尻尾が上がり始めて走行体が走り始めます。 すぐに中止(BACK)ボタンを押して止めます。 LEFTボタンを押すと動的シナリオモードになり、そのときDOWNボタンを押すとBluetoothからの受信待ちになります。 ENTERは受信したのをすぐにスタートするわけですが、なにも受信してないので動きません。RIGHTボタンを押すと、静的シナリオモードになり、コンパイル時に取り込まれたシナリオを実行するモードになります。 なんか、MATLABって凄いわ。

あと、最初の図にもどりますが、真ん中のScenarioCtlGrpが静的シナリオを保持していたり、受信した動的シナリオをバッファに溜めたりして、1回駆動するたびに、シナリオを1行、送り出します。 右上のJudgeCtlは、センサーから入ってきた情報を元に、条件を判定して、成立したかどうかを教えてくれます。 右下のActionCtrlはシナリオの1行で実施するアクション=処理を分類して、操作する内容を送り出します。 この4つ全体でDriverというブロックなのは、人間が自動車のインパネを見ながら、判断して、ハンドルとアクセルを操作する、というモデルに似せています。 実際に自動車を走らせる部分は、DriverのとなりにあるChassisブロックが担当。

こんな具合に、このモデルは動いているわけで、心臓部なわけです。 そういや、久々のモデル審査で、ステートマシン図で書け! というお題に、「それ、アクティビティ図でいいんじゃね?」的なモデルシートがたくさんありましたよねぇ。無理矢理感満載(笑)


MATLAB/SimulinkでETロボコンに出場する:はじめに
MATLAB/SimulinkでETロボコンに出場する:Unityと繋ぐ
MATLAB/SimulinkでETロボコンに出場する:シナリオで振る舞う心臓部
MATLAB/SimulinkでETロボコンに出場する:拡張性が高いアーキテクチャ

| | コメント (0)

MATLAB/SimulinkでETロボコンに出場する:Unityと繋ぐ

今回のMATLAB/SimulinkでETロボコンの出場する、という課題で発掘したネタはたくさんあるんですが、面白いものの1つに、プラントモデルにUnityを採用するにはどうするか? です。 物理モデルを作るツールに、MATLABファミリーにはSimScapeというツールがあるのは知ってるんですが、これがまた高い!29.5万円なり。 オマケに、SimScapeって、厳密で部分的な物理シュミレーションをするにはいいんだろうけど、ETロボコンでコース走ります、という規模のシミュレーションに使えるのかどうかが不明。 

そんな中、ETロボコン東京地区Unity部が、UnityでETロボコン競技会場を見事に再現しているのをみて、もしかして、これでバーチャルな大会できるんじゃね? だったら、検証するためにコース走るぐらいなんて、丁度いいでしょ。 Unityでプラントモデル作るわ。

まー、それにしても、みんなMATLABも初めてだけど、Unityも初めてでして。知らないこと一杯で、どれだけGoogle検索に頼ったことだか。MATLABを調べていると、M言語から.NETアセンブリを簡単に呼び出せることが判明。そしたら、もう、C#でUnityと繋ぐライブラリ「UdpRelay」を作って、UnityもC#でスクリプトを書くのは分かったから、繋げるのは簡単。UdpRelayはその名の通り、ネットのUDP接続でお互い対向する形で通信するライブラリです。Unityの最小最大のステップ幅を0.001秒=1ミリ秒に制限して、Simulinkのシミュレーション時間も1ミリ秒にして、Simulinkからパケットにモーター制御値を入れてUnityへ送り、Unityはそれを受け取ってモーター回して、ジャイロとカラーセンサー値を算出してパケットに詰め込んでSimulinkへ送り返す。これを延々と繰り返します。仕掛けは簡単。

Unity_4

ざっくり図解すると、こんな感じ。3次元座標で頭の中がグリグリ回って大変でしたわ。モーターを回すのも実物のモータートルクを使わないと立たないし。カラーセンサーのRGB値は、カラーセンサーの向いている方向にあるコース上の絵柄を読み取ったり、コースでない物体に当たったときは、その表面の色から算出したり。ソナーも似たような方法。もっとベクトルを勉強しておけばよかったと後悔しきり。 大きさは1を1m、重さは1を1kgとして作り込んでいくと、見事に立つんですねぇ。 あと、反発係数はバウンドさせてみて適当な値にして、摩擦はネットで調べた値を元に、なんとなくな値を設定。

このシミュレーターのお陰で、レプリカコースを広げなくても手軽に実験できるし、EV3セットがなくても全員が試せる。実際に開発現場で起きている、試作機がまだ出来上がってこないとか、試作機台数が少なくて順番待ちとか、そういう問題の解決に同じ手法が使えるという実証実験みたいなもんです。 そして、接続がIPということは、このシミュレーターが地球の裏にあっても、接続して動くということ。 もし相手がUnityでなくて、世界に1台しかない超スーパーコンピューターであったとしても、同じ方式で実現できる、という利点があります。まさかね。

ただ、1つ、現状に欠点がありまして。シミュレーションスピードが遅いんです。シミュレーション内の1秒間を進めるのに、実際には7-8秒掛かる。このまったりとした時間がもったいない。ゆっくり時間が進むので、観察が楽という面もありますが、失敗を何回も微調整して繰り返す場合、ちょっと時間がもったいないかな。 でも、実機でパラメータをイジって、コンパイルして、EV3へ転送して、アプリ起動して、走行体をもって場所に移動して、スタートする。 よりかぜんぜん楽ですが。 時間を短縮しようと、EV3側からプラントモデルにアクセスするのは4ms周期だから、Unity側も4ms周期で動かして同期すれば、速度は4倍になる。 なんて試してみましたけど、1ミリ秒刻みでないと立たないんですわ。 途中の経過が大事なんですね。

Next2018

シミュレーションが自由にできるとなると、再現が難しいことも楽々でして。例えば、タイヤを大きくした走行体が9mm厚の板を走るのは、どれぐらい簡単か、とか。 階段の板の厚みを12mmに変更したら、どれぐらい難しくなるか、とか。 コースの図面にしても、試しにレイアウトしてみて画像が得られたら、張り替えるだけでOK。 なんか凄いね、来年の検討なんて楽勝ですわ。


MATLAB/SimulinkでETロボコンに出場する:はじめに
MATLAB/SimulinkでETロボコンに出場する:Unityと繋ぐ
MATLAB/SimulinkでETロボコンに出場する:シナリオで振る舞う心臓部
MATLAB/SimulinkでETロボコンに出場する:拡張性が高いアーキテクチャ

| | コメント (0)

MATLAB/SimulinkでETロボコンに出場する:はじめに

今年もうちの会社からETロボコンに2チームが出場しまして。1つは新人だけで構成されたチーム「爆速」(名前のとおり爆速で走るのが目標だったけど、結果のほうはどうだったのかね) もう1つは中堅で構成したチーム「巨匠・石山岩尾」(名前の由来はメンバーの苗字を1文字ずつ繋げてみたら、結構、強そうだったとか) 東京地区大会に出場しましたが、チャンピオンシップ大会には進めませんでした。

で、この巨匠チーム。真の目的は、MATLAB/Simulinkで開発してETロボコンに出場して、勝てるぐらいのMATLAB/Smulinkスキルを身につけようぜ! というものでした。で、モデルシートには「大会が終わったら、モデル公開します」と書いてあるし。 が、さすがに中堅どころで業務が忙しくて、そこまで手が回らないので、代わりにここで公開することします。 一応、MATLAB/Simulink技術者を養成するというのが、いまのお仕事の1つなので。

で、開発するに当って、いくつかの要求というか目標がありまして、

1.ぜんぶMATLAB\Simulinkを使って開発する
2.シミュレーションを活用して、開発効率を上げる
3.モデルからコード生成してターゲット開発環境に載せる一連の作業手順を確立する
4.機能拡張を容易にするアーキテクチャにする
5.調整が簡単なアーキテクチャにする


まあ、とくに1-3番あたりはMATLAB/Simulinkで出来るんだよね?という重要事項。4-5番は、このツールを使わなくたって大事なこと。 ですかね。

なんせ、一人前のソフトを揃えるとシミュレーションできるまでが110万円(つまり1-2番ができる) さらにコード生成までできるセットは一人前が240万円もかかります。 スッゲー高いソフトですから、なかなか買えるもんではありません。が、太っ腹の会社。6セット分を買ってくれましたわ!
なので、モデルを公開したところで、MATLAB+Simulink+Stateflowを持っていないと、開いてみることができませんので、HTMLでエクスポートしたファイルをZIPで固めたのを用意しました。 このファイルを解凍して、IshiyamaGanbi2.html ファイルをブラウザで開けば、ブロックをクリックしながら階層構造を開いて、モデルを読むことができます。


「IshiyamaGanbi2.zip」をダウンロード


開くと、トップモデルはこんなふうに見えるはずです。四角いブロックをクリックすると開いて、さらに詳細が見えます。

Modelall


このモデル、ざっと説明すると、下に3個並んでいるのが、EV3に乗っかる部分で、EV3のセンサーとアクチュエータは左右にRealInDev、RealOutDevとして分離されてます。これは、真ん中のTargetModelの入出力をシミュレーターにつなぎ替えてシミュレーションするためです。 上のPlantModelがシミュレーションするための部分。この図の接続はシミュレーションするときの配線で、EV3に載せるコード生成をするときは、バツで示した結線を赤線の方につなぎ替えます。 右上のDashboardというのは、シミュレーションする際に、EV3の前面ボタンを操作したり、走行中のデータを観測したりするダッシュボードが入ってます。 左側にZ-1というDelayが入ってますが、これが一工夫でして、Simulinkってシミュレーションするとき、すべての信号の流れを1つの関数にするみたいで、ループになっていると、無限に関数が終わらない「代数ループ」という状態になるのを防ぐためのもの。

Sim

シミュレーションのプラントモデル、つまり真ん中のTargetModelがセンサーを読んで演算してアクチュエータに出力した結果、走行体に何らかの物理的変化が起こるわけですが、これをどうするか? 最初は簡単な平面のなんちゃってプラントモデルを作ってTargetModelの論理的な確認は出来ていましたが、スタートしてゴールして難所を越えてパーフェクト! という一連の確認をするには本格的な物理シュミレーションが必要なわけで。 そこで、東京地区の人達がUnityを使って実物そっくりのコースに走行体を走らせているのを見て、Unityなら真面目に本物そっくりの大きさ、重さ、トルク、とかでUnityモデルを作ってあげたら、立って走ることも出来るんじゃね? という予測からUnityを使うことにしました。 そのシミュレーションの様子がこれ。


真面目に作ると、ちゃんと立つのが出来るんですわ。Unityって凄い。 そんなわけで、巨匠チームが実機を使って調整を始めたのが、大会1週間前。おいおい、ほんとにそんなんで大丈夫なのかね。

とまあ、シミュレーションの威力を堪能できたわけですが、モデルやシミュレーションについての掘り下げた話は、おいおい追加しておこうと思います。 いやー、MATLABって凄いわ。


MATLAB/SimulinkでETロボコンに出場する:はじめに
MATLAB/SimulinkでETロボコンに出場する:Unityと繋ぐ
MATLAB/SimulinkでETロボコンに出場する:シナリオで振る舞う心臓部
MATLAB/SimulinkでETロボコンに出場する:拡張性が高いアーキテクチャ

| | コメント (0)

BricRoboでブロック並べを解いてみる(6) - BricRoboモデルとソースコード一式

さあ、今回で最終回にします。BricRoboモデル、C#でコード生成したもの(中身を実装済み)、UI画面のC#コード、それら全体をビルドできるVisual Studio 2015のプリジェクトをZIPにして公開します。

まずは以下のZIPファイルをダウンロードして展開してください。
  
  block_narabe.zip

中にあるETR2016.eapはEnterprise Architect(EAと呼びます)のEAPファイルです。BricRoboモデルを見たいという人で、EAを持ってない人はEA+BricRoboをセットにしたインストーラーがあるので、これをダウンロードしてインストールすると、EAでBricRoboモデルを編集して、BricRoboでコード生成することができます。下記のページの一番上の「統合ダウンロード(BricRobo V1.7β+EA)」のダウンロードから入手できます。

  統合ダウンロード(BricRobo V1.7β+EA)

とりあえず、Visual Studio 2015(VS2015と呼びます)があればブロック並べ解法のアプリをビルドできます。展開したblock_narabe.zipの中にあるSlover.slnをVS2015で開いてビルドしてください。最初の章で紹介したアプリができます。

EAPファイルを開くと下の図のような画面構成になります。アルゴリズムのパッケージのなかに、迷路法を解く順序をアクティビティ図で書いたフローチャートがあります。Sloverパッケージはコード生成するためのモデルで、ここからコード生成したC#コードと、別に作ったUI画面のC#コードを一緒にビルドしてアプリが出来てます。
BricRoboパッケージはBricRoboモデルに必ずあるメタモデルで消してはいけません。
見かけないツールバーがありますが、これはEAに追加されたBricRoboのアドインで、BricRoboでモデルを書くときに使います。

Photo_2


EAPファイルのアルゴリズムには下の図のようは感じで、どんな手順で処理していけば解けるのか、フローチャートっぽく書いてます。あとでBricRoboモデルでコマンドを増やしていくとき、どんな処理が必要なんだっけ? と考える拠り所になるので、知らないものを作るときは、ちゃんと書いたほうが後で困りませんからね。

Photo_3

そんなわけで、今日で正月休みも終わるので、これにて終了にしたいと思います。最近、なにか作るときは、BricRoboモデルで作ったらどうなるんだろう? 真っ先に考えるようになりました。慣れなんでしょうね。水中ロボットなどはピッタリ当てはまるので簡単なんですが、こういう解法アルゴリズムとかでも、まずは役目のブロックを書き出して、関係を決めて、全体をどう動かしたら完成するのか? と考えると、大抵のものはできると思えてきました。
異論もあるようですが、オブジェクト指向っていうんだから、まずは実体のあるオブジェクト=ブロックで仕組みを作って、そのブロックを作るためのクラス=部品を考えていくほうが、ずっと簡単。 で、反復しながらクラス=部品を洗練(抽象化したり細分化したり)していくしてくのが王道じゃないかと。

| | コメント (0)

BricRoboでブロック並べを解いてみる(5) - BricRoboモデルへの落とし込み

さて、画面上のサークルの1つ取り上げると、下の図のような形をしてます。真ん中の四角はサークル、上下左右に移動できる経路。迷路法では距離の数字を上下左右に書き込んでいき、その数字を頼って経路を求めたり、数字をクリアしたり、ローバーを移動させたり。なので、今回の考え方は、サークルに能力を持たせて、サークルがいろんな情報を管理して、お互いにやり取りすることで、迷路法を実現させようというもの。

サークルは勝手に動いたり判断しないので、外部から命令を与える必要が。そのために、青のコマンドを外部から与えます。コマンドには情報が付いていて、サークルはコマンドと情報を元に、なにかする。それを全部のサークルに一通り行き渡らせるために、処理したコマンドを次のサークルに投げる。そのとき情報は変化しているかもしれない。

例えば、「ローバーのいる場所を教えて!」というコマンドがあり、情報に-1(知らないという意味)を設定して、サークルに流す。受け取ったサークルは「おれ、知らない、次へ」とコマンドを次のサークルに流す。知っているサークルは「俺のところに居る、10番のサークルだよ」と情報に10をセットして次へ流す。 そうすると、巡って最後に流れてきたコマンドには情報に10が書いてあるので、10番のサークルにローバーがいるな! と分かるわけです。

別の例で言うと、「距離計測してるんでよろしく」というコマンドを作り流す。貰ったサークルは赤矢印の自分の方にどこからか番号が流れてきたかなぁ、と見てみる。 「あ、5が届いてるわ。じゃ、自分の距離は5とおぼえて。+1して6を緑矢印の向きへ流さなきゃ」 これをすべてのサークルが繰り返すと、迷路法でやった数字を埋めるのと同じことができる。

こんなコマンドをたくさん作って、サークルが受け取ったときにどんな処理をするかをサークルに仕込んでおくわけです。

Zukai_2

この方式のいいところは、上下左右という形に左右されない。星型につながっていてもいいし、6方向でも8方向でもいい。どんな形にしてもサークルのやることは変わらないところです。これ大事ね。 それからサークルにさせたいことが増えたら、コマンドを増やして対応する。これもアーキテクチャが変わらないから大事。

そこで図の下側になるんですが、BricRoboモデルの1つのサークルへ対応させてものが、これ。BricRoboモデルの読み方を知らない人のために、ちょっとだけ解説しますが、青と赤の小さい四角はポートと呼んで、データをやり取りする接続口です。青はデータ型といって、ポートに届いた情報を何回読み出しても読み出せる性質。赤はイベント型といって、ポートに届いた情報を読み出すと、空っぽになって2回目以降は届かない限り読めない性質。
そして白抜きの△は受信、塗りつぶし▲は送信の性質。 このブロックがたくさん繋げて4x4の形にしたのが、前の章で出てきた、あの複雑に線が引かれたBricRoboモデルなわけです。 そして、コマンドを画面から入れるためのブロックが左側の黄色ブロック。最後に流れ着いたコマンドを拾い上げるのが右下の緑ブロックってわけ。
なんとなく、仕組みは分かってもらえましたかね?

Field


>>BricRoboでブロック並べを解いてみる(6) - BricRoboモデルとソースコード一式

| | コメント (0)

BricRoboでブロック並べを解いてみる(4) - 迷路法をブロック並べに応用

前の章では複雑に線が入り組んだBricRoboモデルが出てきました。これに画面の絵を当てはめると次のよな図になります。ブロック並べのフィールドそのものですが、黒線は移動できる経路を示したもの。本来は一番右端に縦に黒線が1本ありますが、最後はそこに抜け出たいので、その場所をゴールとして、右側へ抜ける4本の経路を引いておきました。(これはあとでちょっと問題があるんですが)

Photo

そして、この配置は次の図のように、一番最初に迷路法を説明したときの四角が連なった迷路とみなすことができますよね。だから、この図を元にして、どうやってブロック並べを解いていくか、例を使って説明していきます。

Photo_2


最初はこんな配置だとします。一番左にローバー、4つのブロックは緑、黒、青、赤。みんな違う色のサークルの上にあります。-1の数字は、その場所になにも距離の値、迷路法で数字を入れていないことを表しています。

Photo_4


まずはスタート地点であるローバーの位置に0を入れます。

Photo_3


次に0の回りに1を入れていくのですが、黒線で繋がった場所にしか動けないので、黒線で0と繋がった枠に1を入れるとこんな感じ。

Photo_5


次に1と黒線で繋がった枠に2を入れます。するとこんな感じ。青ブロックのところに2が入りました。

Photo_6


次に2と黒線で繋がった枠に3を入れます。ここで注意しないといけないのは、青ブロックは要するに壁なので、青ブロックにある2は無視すること。そうしないと壁を突き破って進んで行けることになるので。

Photo_7


次に3と黒線で繋がった枠に4を入れます。緑ブロックも黒ブロックも3が入ってますが、それは壁なので伸びません。下の赤いサークルの3だけが右に伸びて4が入ります。

Photo_8


次に4と黒線で繋がった枠に5を入れます。赤ブロックにも5が入って、ブロックは全部埋まりました。もうブロックまでの経路はわかったのですが、一律の動作にしたいので、枠に数字が入れられなくなるまで続けます。

Photo_9


次に5と黒線で繋がった枠に6を入れます。

Photo_10


次に6と黒線で繋がった枠に7を入れます。あれ?右側の楕円のサークルに7が入ってしまいました。これがまだ細工が足りないところで、ここはゴールのサークルなんですが、特別扱いしてないので7が入ってしまいました。つまり経路の1つとして使ってしまったわけ。これはあとで条件を加えれば回避できるので、とりあえずほっときます。

Photo_11


次に7と黒線で繋がった枠に8を入れます。これで-1の枠はなくなり全部に値がはいりました。-1が消えたということはローバーがいけない場所はないということです。

Photo_12


さて、ローバーから一番近いブロックはどれかというと、数字を0から1つずつあげてブロックのある場所を探すと、それは2の入っている青ブロック。青ブロックの2から数字を1つずつ小さくしながら枠を辿るとローバーのところまで戻ってこれます。これがローバーから青ブロックまでいく経路。

Photo_13


経路が分かったので、青ブロックまで移動。

Photo_14


次は青ブロックを運ぶ場所を探します。やり方は一緒で、ローバーのいる位置を0として、これまでと同じ方法で数字を書き込んでいきます。するとこんなふうに枠に値がハマって、青サークルで一番数字が小さいところが青ブロックを運ぶ場所で、1から値を小さくしながら辿るとローバーのところに戻ってこれるので、これが青ブロックを運ぶ経路なわけ。

Photo_15


これで青ブロックの移動終了。あと緑と赤を運ばないと。

Photo_16


これまでと同じようにして、ローバーのいる場所に0をいれて、そこから全部の枠に数字を入れていきます。そうするとこんな感じになります。

Photo_17


黒以外で、ブロックとサークルの色が合っていないので、数字が一番小さいのは2の赤ブロック。次はこれを運ぶために経路は2から数字を小さくしながら戻るとこんな経路。

Photo_18


赤ブロックまでローバーを移動します。

Photo_19


ローバーのいる場所を0としてまた数字を埋めていきます。赤サークルで一番数字が小さいのは2の場所。そこが赤ブロックを運ぶ場所で運搬ルートです。

Photo_20


赤ブロックを運びます。だんだん面倒くさくなってきたね。あと緑ブロックだけ。

Photo_21


同様にしてローバーの場所に0を入れて回りを埋めていきます。この時、緑ブロックまでのルートは2つあります。4,3,2,と辿ってくると、2から1へは2通りあります。どちらも0まで戻ってこれるのですが、どちらを選ぶかは数字の探す順番できまります。いまのプログラムは下側が選ばれました。 で、緑ブロックまでのルートが見つかりました。

Photo_22


緑ブロックまでローバーを移動させます。

Photo_23


また、ローバーのいる場所を0にして回りの数字を埋めていきます。緑サークルで一番小さい数字の場所が緑ブロックを運ぶところ。経路も分かります。

Photo_24


緑ブロックを緑サークルまで運びます。

Photo_25


さあ、ブロックは全部運び終わったので、ゴールまでの経路を求めます。ローバーの場所を0として回りの数字を埋めていきます。するとゴールまでのルートが求まります。

Photo_26


ローバーをゴールまで移動させます。 これで終了。長かったね。

Photo_27


やることは同じで、

1.ローバーの場所から数字を埋めて、一番近いブロックを探す。
2.ブロックまで移動する。
3.ブロックの位置から数字を埋めて、一番近い同じ色のサークルを探す。
4.サークルまでブロックを移動する。

これを繰り返して、動かすブロックがなくなったら、最後はゴールまで経路を探して出ていく。
ローバーをターンさせたりブロックの向こう側に更に進めたり、そういう制御の難しさはぜんぜん考慮してないけど、一応、迷路法を使ってブロック並べは解けることは分かりました。

次は、数字を埋めたり、経路を探したりするのに、サークルに機能を持たせて、それをどうやって駆動して全体を動かしていくのか、の話ですかね。


>>BricRoboでブロック並べを解いてみる(5)

| | コメント (0)

BricRoboでブロック並べを解いてみる(3) - アプリの仕組み

何ができるかわかったところで、仕組みがどうなっているか見てみます。画面でちょこまか動いているのはローバーやブロックを動かした結果を表示しているだけで、実際の情報はBricRoboのモデルとして作られた中にあります。
この図の上の部分が見えている画面。画面上のサークルやローバーやブロックは、BricRoboモデルで作成した中身を反映しているだけです。

では色分けした部品が何をしているかというと、

■青色
サークルを表しています。サークルが持つ情報には、自分はどの位置なのか、何色なのか、ブロックが乗っているのか、ローバーが乗っているのか、ゴールなのか、迷路法で計算した距離、などです。


■黄色
サークルに対してコマンドを発行します。あとで説明しますが、サークルはコマンドを受け取ると何か処理をします。そのコマンドを画面からもらってサークルに流す役目をします。

■緑色
サークルから流れてきた最後のコマンドを受け取り、画面側に提供します。黄色から流れたコマンドは、サークルを巡って最後にここに流れ着きます。調べるコマンドは、この流れ着いたコマンドの中に知りたい値が入っています。

■ピンク色
サークルにブロックを置きます。ブロックを置く場合にはサークルと同じ色のところに同じ色のブロックを置かないとかいろいろ置き方があるので、その辺の処理はここで受け持ちます。


Photo_2

この下側の実際に迷路法を解いている部分。BricRoboモデルの実物は次の図になります。凄い複雑そうに見えるでしょ。でも、書いてあることは上の図の通りで、4x4マス目の上下左右の繋がりをポートの結線で表しているので、こんなにたくさん線が引いてあるのです。

しかし、ここで気づきますよね。サークルの繋がりを結線で表しているので、どんな形でも関係ないんですわ。平面の2次元でなくても3次元でもOK。複雑になるなら、3次元の層ごとに別のダイアグラムに分けて書けばいいわけで。

なんで、こんなもので迷路法が解けるのか? という仕組みについては、次回で解説します。

Field


>>BricRoboでブロック並べを解いてみる(4) - 迷路法をブロック並べに応用

| | コメント (0)

BricRoboでブロック並べを解いてみる(2) - ブロック並べ解法アプリ

さて、経路探索のアルゴリズムは決めたので、これを使って実際にどういうものが出来上がるかのビデオ。 最終的にこんな風になります。純粋に経路を探してブロックを運ぶだけなので、実物のロボット制御がない単純なもの。この通りにロボットを制御するのは、また別の難しさになるので、それは今回の目的じゃないです。

画面にはサークルとブロックとローバー(つまり走行体です)があって、最初にブロックをセットして、ローバーを進入口にセットして、一番近くのブロックから順番に、同じ色のサークルへ移動して、最後はゴールするというもの。
ボタンの意味は、

RESET BLOCK:ブロックを消し去って初期化する
OMMIT:使わないブロック色の選択
NEXT BLOCK:次のブロック配置
RAND BLOCK:乱数でブロック位置を決定
SET ROVER:ローバーを進入口へセット

SEARCH ROUTE:ローバーから一番近い移動が済んでないブロックまでのルートを探す
GOTO BLOCK:見つけたブロックまでローバーを移動する
SEARCH ROUTE:ローバーの位置からサークルまでの距離を計算する
CARRY BLOCK:一番近い同じ色のサークルまでブロックを運ぶ
AUTO:上記の4つを順番に自動で行う

ALL PATTERN:全部のブロック配置についてやってみる
画面更新:そのとき画面を更新する(計算を速くするには画面更新を止めるのがいい)

ひみつ:じつは昔、この画面を流したとき何をしているか分からないように、ルートの距離を非表示にする機能をつけた

LOG:ブロック配置に対してローバーがゴールできたか、できたらその移動数はどれだけか、のログをファイルに保存する

Ui

ログファイルにはこんな形式で記録されていきます。
左から黄緑赤青黒の位置、ブロックが置かれた位置を16進表記にしたもの、ブロックの移動回数、最後まで解けたかどうか。

Log

位置に関しては、こんな風に番号を付与してあります。今回は4x4マス目で、丁度、0-15に対応させると表現し易いのでこのようにしてますが、結果をどう表現するかの問題なので、解法とは関係はないです。

Photo

この迷路法で近くのブロックから手当たりしだいに移動すると、考えなしなので、手詰まりが発生して、解けない! というブロック配置が出てくるのですが、それがどれぐらいあるのか?とか、どれぐらいの移動距離のバラつきがあるのか。ということを調べたりしていたわけです。 巷ではダイクストラ法というのが流行りみたいですね。そんなの知らんかったです。 けど、どのみち、経路探索にしか使わなければ、手詰まりが発生するのは同じでしょうけど。 手詰まりが発生したらどうするか? ブロックを動かす優先順位を遠くからに変えてみるとか、なるべく遠くのサークルに置くような評価にするか、なんか変化を加えてみれば解ける場合もあるんでしょうね。

>>BricRoboでブロック並べを解いてみる(3) - アプリの仕組み

| | コメント (0)