今回の課題では,コースの上と箱の中においてあるボールをもう一つの箱の中にシュートするというものである.
(以下のリンクを参照) 2019a/Mission3
今回の課題を攻略する上で,私たちのグループは次のような二台のロボットを使用するという作戦を立てた.
地面に落ちているボール担当のロボットは一つのボールをとるまではライントレースをし,二つ目のボールは場所を計算しプログラムを作成した.
箱の中のボール担当のロボットは構造上ライントレースをするとアームが箱にぶつかってしまうので線を無視してプログラムを作成した.
基本的な構造は前回と同様で,まず最初に車輪を含む土台をつくり,その上に本体とアームを乗せた形になっている.安定性を高めるため,できるだけ重い本体は下に設置し重心を下にもっていくように工夫した.コードなどはアームに取り付けた坂の隙間を利用し,まとめた.
下図は地面に落ちているボールをとるアームである.まず輪ゴムがついてある先端部分をボールに叩きつけ,輪ゴムと輪ゴムの間に入り込ませる,次に入り込んだボールを持ち上げ,一番上まで持ち上げたときにボールが転がりアームの後ろについている坂を下りてゴールにシュートするという仕組みとなっている.とったボールが確実に坂をまっすぐ下りるように斜めにパーツをつけたりなどの工夫をした.
下図は箱の中のボールをとるアームである.元となる発想は地面に落ちているボールをとるアームと同じで,二本のアームを箱の横にいれ,持ち上げることによりボールを転がし坂を通ってゴールにシュートするという仕組みになっている.ボールをシュートする際,箱が一緒に落ちないように固定するアームを取り付けるなど工夫をした.しかしその反面アームが長すぎてラインをトレースすると箱に当たってしまうのですべて自分たちでプログラムを作り,微調整した.
まず最初にdefineで様々な数字や動作を定義した.
#define MOVE_TIME 250 //交差点を判断する際に用いる条件 #define SPEED_H 35 //車輪の速さ(速い) #define SPEED_L 20 //車輪の速さ(遅い) #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); //車輪を動かす際の速さや向きを「speedR」と「speedL」で定義する #define go_straight OnRL(SPEED_H,SPEED_H); //まっすぐ進む #define rot_r OnRL(-SPEED_L,SPEED_L); //右回転 #define turn_r OnRL(0,SPEED_L); //右折 #define rot_l OnRL(SPEED_L,-SPEED_L); //左回転 #define turn_l OnRL(SPEED_L,0); //左折 #define B1 43 //二番目に暗い #define G 53 //真ん中 #define W1 59 //二番目に明るい #define W2 61 //一番明るい #define BACK OnRL(-SPEED_H,-SPEED_H); //後進
今回の交差点の判断の条件は前回と同様である.一番暗いとき以外のときは動作を終了するたびに基準の時間をリセットし,一番暗いときはリセットしないことによって一番暗いときがMOVE_TIMEの長さ続いた場合に交差点であると認識するようになっている.
sub follow_line_l() { SetSensorLight(S2); //光センサーを起動 long t0=CurrentTick(); //基準を定義 while(CurrentTick()-t0<MOVE_TIME){ //基準からMOVE_TIMEまで動作を続ける if(SENSOR_2>W1){rot_r;t0=CurrentTick();} //光センサーの値>W1のとき右回転,時間をリセット else if(SENSOR_2>W2){turn_r;t0=CurrentTick();} //光センサーの値>W2のとき右折,時間をリセット else if(SENSOR_2>G){go_straight;t0=CurrentTick();} //光センサーの値>Gのとき前進,時間をリセット else if(SENSOR_2>B1){turn_l;t0=CurrentTick();} //光センサーの値>B1のとき左折,時間をリセット else{rot_l;} //上以外のとき左回転 } }
sub short_break() { Off(OUT_BC); Wait(1000); }
これはボールをキャッチする際の,アームを下げるプログラムである.万が一アームが移動中に下がってしまったときのためにまず最初にアームを一番上まで上がるようになっている.
sub arm_down() { OnFwd(OUT_A,70); Wait(600); Off(OUT_A); Wait(500); OnRev(OUT_A,50); Wait(500); Off(OUT_A); }
sub shoot() { OnRev(OUT_A,60); Wait(700); Off(OUT_A); OnFwd(OUT_A,55); Wait(500); Off(OUT_A); }
sub back(long t) { BACK; Wait(t); Off(OUT_BC); }
task main() { Off(OUT_A); go_straight; Wait(1000); Off(OUT_BC); //スタート
follow_line_l(); short_break(); //M'からK'までライントレース
rot_r; Wait(400); Off(OUT_BC); go_straight; Wait(800); Off(OUT_BC); arm_down(); //ボールをキャッチ
turn_r; Wait(3500); Off(OUT_BC); shoot(); //ボールをゴールにシュートする
Wait(1000); rot_r; Wait(3900); Off(OUT_BC); go_straight; Wait(6600); Off(OUT_BC); arm_down(); //二つ目のボールをキャッチ
back(3000); OnRL(0,-SPEED_L); Wait(300); Off(OUT_BC); shoot(); //ボールをゴールにシュートする }
箱の中のボールは地面に落ちているボールと違い,線を辿らずにすべてプログラムを自分たちで作成して微調整した.そのため本番ではいまいち片方のロボットと連携できず,失敗してしまった.
#define SPEED_H 35 #define SPEED_L 20 #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); #define go_straight OnRL(SPEED_H,SPEED_H); #define rot_r OnRL(-SPEED_L,SPEED_L); #define turn_r OnRL(0,SPEED_L); #define rot_l OnRL(SPEED_L,-SPEED_L); #define turn_l OnRL(SPEED_L,0); #define BACK OnRL(-SPEED_H,-SPEED_H);
sub shoot() { OnRev(OUT_A,60); Wait(600); Off(OUT_A); OnFwd(OUT_A,90); Wait(800); Off(OUT_A); }
task main() { go_straight; Wait(1000); Off(OUT_BC); rot_l; Wait(2800); Off(OUT_BC); go_straight; Wait(3000); Off(OUT_BC); rot_l; Wait(4500); Off(OUT_BC); //箱ごとキャッチ
go_straight; Wait(3000); turn_l; Wait(8700); Off(OUT_BC); Wait(27000); OnFwd(OUT_A,50); Wait(700); OnRev(OUT_BC,60); Wait(700); Off(OUT_BC); shoot(); //ボールをゴールにシュートする }
ロボットを設計するとき,グループで一機でするか,二機でするかで少し口論になった.最初は僕は二つのロボットを合体させてアームを二つのモーターで動かす方がいいといいと思っていた.しかし,同じグループの一人がダンプカーのようなものはどうかという言葉で今回のようなモーター三つで処理をするロボットを思いついた.地面のボールは輪ゴムでクリアできたが,箱の中のボールはそれではうまくできなかったので他の方法を探した.下ろしたときにアームが閉じ,上に上がった時に開くアームや,スライド式のアームに輪ゴムを取り付け,上から押さえつけてとる方法など様々な仕組みを思いついたがどれもうまくいかなかった.そして結局箱ごと持ち上げてシュートする構造を採用した.箱の中にボールがなかったらもう少しうまくできていたかもしれない.
ロボットの構造上,箱担当のロボットはほとんど線をたどらないプログラムを作らなければならず,何回調整しても動かすたびにずれたりすることが多かった.結局本番では本番と直前のリハーサルとで誤差が生じ,思っていたより動きが速くなってしまいもう一つのロボットにぶつかってしまった.これはプログラムの問題というよりロボットの構造の問題だったように思える.
今回の課題は最後というだけあって,とても難しかった.特に箱の中のボールをどうやって攻略すればいいのか,様々な方法を考えたが結局ほとんどはうまくいかなかった.リハーサルや直前,リハーサルではうまくいっていたのに本番ではボールが一つしか入らなかったのでとても悔しかった.もっと誤差が少なくなるようなプログラムや構造を作ることができればよかったなとおもった.しかし,全グループの中で三位になれたので良かった.また,この講義でロボットは自分たちが思っているほど正確ではないのだと感じた.どれだけ微調整を繰り返してもすこし環境が違えば大きな誤差ができ,うまくいかなかった.また,逆に普段使っている機械は誤差が起きても最小限に抑える工夫がなされているのだなと感じた.将来機械をつくる職に就くかもしれないのでぜひこのことは肝に銘じておきたいと思った.