目次
詳しくは2017a/Mission3を参照
図の通り、AからスタートしてライントレースをしEにある缶を掴み、再びライントレースを続け、赤い丸のある缶の上にのせてGOALのTに持っていくプログラムである。 一度外側のライントレースを内側のライントレースに変えることでロボットが線の内側寄りになり缶を積み上げやすくなっている。
試行錯誤の結果このような形になった。
写真にある三角形の部分は、缶が横にずれた場合にズレを直すためについている。 また缶を持ち上げる時、缶を落としてしまうことがあったのでゴムなどつけ、滑りにくくした。
缶を持ち上げてもアームの重さで勝手に下がってきてしまうのを治すことにとても苦労した。 その結果出来上がったのが写真の構造である。先生のアドバイスを参考に作成した。 アームの重さと釣り合うようにモーターをつけ、天秤のようにすることで先に挙げた問題点を解消した。しかし、釣り合わせるためモーター以外にも部品を付けたので、ロボットが重くなってしまいタイヤの回りが悪くなってしまうという新たな問題が出てきてしまった。本番には間に合わなかったが、タイヤとモーターを直接繋ぐのではなく、ギアなどを噛ませてやればよかった。
動き方は、「課題について」で説明している。 今回はbluetooth機能を使用し、モーターの動きを角度で指定することで、電池の状況で左右しないようになっている。
タイヤを動かす部分を担っている。
/ マスター側(タイヤ、センサー) /* B -> 右のモーター C -> 左のモーター S1 -> 光センサー S2 -> 超音波センサー */
定義
#define CONN 1 // スレーブの接続番号 #define SPEED 40 #define OROSE 11 // アームを降ろさせる #define TOJIRO 12 // 缶を掴ませる #define AGERO 13 // アームを上げさせる #define HIRAKE 14 // 缶を離させる #define TUM 15 // 缶の上まで下ろす #define RYO 16 // 完了 #define SIRO0 47 // 白のしきい値 #define SIRO1 54 #define KURO0 42 // 黒のしきい値 #define KURO1 37
ライントレース
sub line_l() //左側のライントレース { SetSensorLight(S1); if (SENSOR_1 > SIRO1){ Off(OUT_B); OnFwd(OUT_C,SPEED); } else if (SENSOR_1 > SIRO0){ OnFwd(OUT_B,20); OnFwd(OUT_C,SPEED); } else if (SENSOR_1 > KURO0){ OnFwd(OUT_BC,SPEED); } else if (SENSOR_1 > KURO1){ OnFwd(OUT_B,SPEED); OnFwd(OUT_C,20); } else { OnFwd(OUT_B,SPEED); Off(OUT_C); } } sub line_r() // 右側のライントレース { SetSensorLight(S1); if (SENSOR_1 > SIRO1){ Off(OUT_C); OnFwd(OUT_B,SPEED); } else if (SENSOR_1 > SIRO0){ OnFwd(OUT_C,20); OnFwd(OUT_B,SPEED); } else if (SENSOR_1 > KURO0){ OnFwd(OUT_BC,SPEED); } else if (SENSOR_1 > KURO1){ OnFwd(OUT_C,SPEED); OnFwd(OUT_B,20); } else { OnFwd(OUT_C,SPEED); Off(OUT_B); } }
アームの動き
sub orose(int t) // アームを下ろす { int msg; SendRemoteNumber(CONN,MAILBOX1,OROSE); Wait(t); } sub hirake(int t) // アームを開く { int msg; SendRemoteNumber(CONN,MAILBOX1,HIRAKE); Wait(t); } sub tojiro(int t) // 缶をつかむ { int msg; SendRemoteNumber(CONN,MAILBOX1,TOJIRO); Wait(t); } sub agero(int t) // アームを上げる { int msg; SendRemoteNumber(CONN,MAILBOX1,AGERO); Wait(t); } sub tum(int t) // 二段目まで下ろす { int msg; SendRemoteNumber(CONN,MAILBOX1,TUM); Wait(t); }
一連の動き
sub iti() // Eの缶と一番上の缶 { SetSensorLight(S1); SetSensorLowspeed(S2); until (BluetoothStatus(CONN) == NO_ERR); hirake(1000); while(SensorUS(S2) > 10){ 缶とロボットの距離が10cmになるまで進む OnFwdSync(OUT_BC,SPEED,0); } Off(OUT_BC); tojiro(1000); long t0 = CurrentTick(); //時間を導入(導入下時を0とする) while(CurrentTick()-t0 < 7000){ //時間内(7秒)にだけライントレース line_l(); } OnFwd(OUT_B,-40); OnFwd(OUT_C,40); Wait(700); t0 = CurrentTick(); //このとき時間を0にする while(CurrentTick()-t0 < 2500){ //時間内(2,5秒)だけライントレース line_r(); } t0 = CurrentTick(); //このとき時間を0にする while(CurrentTick()-t0 < 1000){ //時間内(1秒)だけ前に進む OnFwdSync(OUT_BC,SPEED,0); } Off(OUT_BC); Wait(500); RotateMotor(OUT_BC,-SPEED,65); Wait(100); agero(3000); while(SensorUS(S2) > 15){ //缶とロボットの距離が15cmになるまで進む OnFwdSync(OUT_BC,SPEED,0); } Off(OUT_BC); tum(3000); Wait(500); while(SensorUS(S2) > 10){ //缶とロボットの距離が10cmになるまで進む OnFwdSync(OUT_BC,SPEED,0); } Off(OUT_BC); tojiro(1000); OnFwd(OUT_BC,60); Wait(500); Off(OUT_BC); RotateMotor(OUT_C,SPEED,250); Wait(1000); Off(OUT_BC); OnFwd(OUT_BC,40); Wait(1000); Off(OUT_BC); hirake(1000); }
task main
task main(); { iti(); }
アームを動かしたり缶を持ち上げる部分を担っている。
// スレーブ側(アーム) /* A -> アームの開閉のモーター OnFwdで開く B -> アームの上下のモーター OnFwdで下ろす */
定義
#define CONN 0 // マスターの接続番号 #define SPEED 40 #define OROSE 11 // アームを降ろさせる角度 #define TOJIRO 12 // 缶を掴ませる角度 #define AGERO 13 // アームを上げさせる角度 #define HIRAKE 14 // 缶を離させる角度 #define TUM 15 // 缶の上まで下ろす角度 #define RYO 16 // 完了の時の角度
一連の動き
sub arm() { until (BluetoothStatus(CONN) == NO_ERR); while(true){ int msg; ReceiveRemoteNumber(MAILBOX1,true,msg); if (msg == OROSE){ // アームを下ろす Wait(100); RotateMotor(OUT_B,SPEED,360); } if (msg == TOJIRO){ // 缶をつかむ Wait(100); RotateMotor(OUT_A,-SPEED,50); } if (msg == AGERO){ // アームを上げる Wait(100); RotateMotor(OUT_B,-60,600); } if (msg == HIRAKE){ // 缶をはなす Wait(100); RotateMotor(OUT_A,SPEED,50); } if (msg == TUM){ // 二段目まで下ろす Wait(100); RotateMotor(OUT_B,SPEED,120); Wait(100); RotateMotor(OUT_A,SPEED,50); Wait(100); RotateMotor(OUT_B,SPEED,360); } } }
task main
task main() { arm(); }
プログラムは出来ているものの調整が間に合わなかったり、itiが完璧にできるようになっていなかったなどがあり、本番で使えなかったプログラムである。
sub ni() // FとTの缶 { SetSensorLight(S1); SetSensorLowspeed(S2); OnRev(OUT_BC,SPEED); Wait(1000); OnFwd(OUT_B,-SPEED); OnFwd(OUT_C,SPEED); Wait(500); until (SensorUS(S2) < 40) Off(OUT_BC); orose(1000); hirake(1000); OnFwdSync(OUT_BC,SPEED,0); until (SensorUS(S2) < 20); tojiro(900); agero(1300); while(SENSOR_1 > SIRO0){ OnFwd(OUT_BC,SPEED); } while(SensorUS(S2) > 20){ line_l(); } Off(OUT_BC); tum(1000); tojiro(1000); OnFwd(OUT_B,SPEED); Off(OUT_C); Wait(100); hirake(1000); agero(1300); }
練習中では、なかなか安定して缶を積み上げることができず、案の定、本番では失敗し0点だった。 松本先生がおしゃっていた期間内に仕上げる難しさを痛感した。しかしこの講義を通して協力する力と問題解決能力が養われたと考える。