[[2019a/Member]]~ &size(40){課題3};~ ~ &size(20){目次};~ #contents *ルート [#q735a024] 私たちは、~ A→M→K→L→K→J→…~ というルートでプログラムを書きました。 #ref(ルート.png) *ロボットについて [#l03cd49c] ロボットはRIS本体を縦に2つ繋げて、それを水平に対して直角に立てました。~ RIS本体を縦に2つ繋げた理由は、通信がうまくできるからです。~ それを水平に対して直角に立てた理由は、横にするとロボットが~ 大きくなってしまうからです。~ アームに関しても、アームを回転させることで持ち上げるようにしたのは、~ アームをできるだけ小さいスペースで取り付けたかったからです。 アームをできるだけ小さいスペースで取り付けたかったからです。~ なので、完成したロボットは縦には長いが、横はコンパクトです。 #ref(全体像.JPG) *ロボットの説明 [#vfea1ed1] **ピンポン玉を掴むパーツ [#x2db7e1d] ピンポン玉をつかむ仕組みは、ピンポン玉をゴムの力を利用して、~ アームと一体化させるようにしました。~ また、アームが無理やり開こうとするのを制御するため、~ 白い歯車を使用しました。 #ref(ピンポン玉を掴むパーツ2.JPG) **ピンポン玉を持ち上げるパーツ [#vde8bc5c] ピンポン玉を持ち上げるパーツは、モーターを2つ使いました。~ 始めは1つにしていたのですが、力が足りなかったので増やしました。 #ref(アームを上げるパーツ.JPG) **後輪 [#v2e2da28] 後輪は、アームを上げるときの反動で、一時的に後ろに力が加わるので、~ それを支えるために取り付けました。~ 動いているときに摩擦がおきくくなるように、360度回転できるようにしました。 #ref(後輪.JPG) **全体像 [#z7b34202] 完成したロボットは縦には長いが、横はコンパクトになりました。 #ref(全体像.JPG) *プログラムの説明 [#zc439833] **送信側のプログラム [#p11114ae] ***準備のプログラム [#ed26b62f] #define OPEN 13 //アームを開くメッセージの番号 #define UP 14 //アームを上げるメッセージの番号 #define FREEZE 15 //何もせず止まるようにするメッセージの番号 #define black 37 //ラインの右側をトレースするサブルーチン sub intersection_stop_rightside(){ ClearTimer(0); //最初にタイマーをリセットしておく while(FastTimer(0)<30){ if(SENSOR_2 > black){ //白のラインをトレースしている時 OnFwd(OUT_C);Off(OUT_A);ClearTimer(0); }else if(SENSOR_2 < black){ //黒のラインをトレースしている時 OnFwd(OUT_A);Off(OUT_C); } } Off(OUT_AC); //最後はロボットを停止させて終了する } //ラインの左側をトレースするサブルーチン sub intersection_stop_leftside(){ ClearTimer(0); //最初にタイマーをリセットしておく while(FastTimer(0)<30){ if(SENSOR_2 > black){ //白のラインをトレースしている時 OnFwd(OUT_A);Off(OUT_C);ClearTimer(0); }else if(SENSOR_2 < black){ //黒のラインをトレースしている時 OnFwd(OUT_C);Off(OUT_A); } } Off(OUT_AC); //最後はロボットを停止させて終了する } //交差点で止まるサブルーチン sub corner_stop(){ ClearTimer(0); //最初にタイマーをリセットしておく while(FastTimer(0) < 63){ if(SENSOR_2 < black){ //白のラインをトレースしている時 OnFwd(OUT_C);Off(OUT_A);ClearTimer(0); }else if(SENSOR_2 > black){ //黒のラインをトレースしている時 OnFwd(OUT_A);Off(OUT_C); } } Off(OUT_AC); while(SENSOR_2 > black){ //黒のラインをトレースしている時 OnFwd(OUT_A);OnRev(OUT_C); } Off(OUT_AC); //最後はロボットを停止させて終了する } ***プログラムの中身 [#s5ee6de3] task main() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); FastTimer(0); ClearMessage(); intersection_stop_rightside(); //ヘアピンカーブで停止する corner_stop(); OnFwd(OUT_A);OnRev(OUT_C);Wait(180); //反転する SendMessage(OPEN); //アームを開けるメッセージを送信する OnFwd(OUT_AC);Wait(100); //ピンポンボールまで進む ClearMessage(); //アームを閉じる OnFwd(OUT_C);OnRev(OUT_A);Wait(130); //箱の正面まで回転 Off(OUT_AC); SendMessage(UP); //アームを上げるメッセージを送信する OnFwd(OUT_AC);Wait(100); //箱まで進む ClearMessage(); //アームを下げる SendMessage(OPEN); //アームを開くメッセージを送信する SendMessage(UP); //アームを上げるメッセージを送信する OnRev(OUT_AC);Wait(100); //箱から離れる Off(OUT_AC); ClearMessage(); //アームを下げる } **受信側のプログラム [#w933e82b] ***準備のプログラム [#meb476d3] #define OPEN 13 //アームを開くメッセージの番号 #define UP 14 //アームを上げるメッセージの番号 #define FREEZE 15 //何もせず止まるようにするメッセージの番号 #define open(t) OnFwd(OUT_B);Wait(t);OnRev(OUT_B);Wait(5); //アームを開く番号 #define up(t) OnFwd(OUT_AC);Wait(t); //アームを上げる番号 ***プログラムの中身 [#h2d5f6d0] task main() { ClearMessage(); while(true){ ClearMessage(); while(Message() == OPEN){ //OPENを受信したとき open(300); //3秒開く } Off(OUT_AC); //処理が終わったら停止 while(Message() == UP){ //UPを受信したとき up(300); //3秒開く } Off(OUT_AC); //処理が終わったら停止 } } **連続して黒になる時間の計り方 [#ff8b6e35] 今回は、全てのサブルーチンが、連続して黒になる時間を~ 計っています。~ なので、全てのサブルーチンに、このパラグラフの~ 一番最後に書かれているプログラムの構造が適応されています。~ したがって、そのプログラムについて説明したいと思います。 +まず初めにタイマーをリセットする。(ClearTimer(0);) +タイマーが[時間]未満なら、whileループが実行される。 +ライトセンサーが白の上にいるときは、処理後にタイマーをリセットする。 +ライトセンサーが黒の上にいるときは、処理後にタイマーがリセットされず、~ whileの条件のFastTimer(0)に代入される。 sub [サブルーチン名]{ ClearTimer(0); //1番、4番 while(FastTimer(0) < [時間]){ //2番 if(SENSOR_2 > black){ //白のラインをトレースしている時 [プログラム1] ClearTimer(0); //3番 }else if(SENSOR_2 < black){ //黒のラインをトレースしている時 [プログラム2] } [プログラム3] } } *プログラム全体 [#bee96ab2] **送信側 [#r3cfbf61] #define OPEN 13 //アームを開くメッセージの番号 #define UP 14 //アームを上げるメッセージの番号 #define FREEZE 15 //何もせず止まるようにするメッセージの番号 #define black 37 //ラインの右側をトレースするサブルーチン sub intersection_stop_rightside(){ ClearTimer(0); //最初にタイマーをリセットしておく while(FastTimer(0)<30){ if(SENSOR_2 > black){ //白のラインをトレースしている時 OnFwd(OUT_C);Off(OUT_A);ClearTimer(0); }else if(SENSOR_2 < black){ //黒のラインをトレースしている時 OnFwd(OUT_A);Off(OUT_C); } } Off(OUT_AC); //最後はロボットを停止させて終了する } //ラインの左側をトレースするサブルーチン sub intersection_stop_leftside(){ ClearTimer(0); //最初にタイマーをリセットしておく while(FastTimer(0)<30){ if(SENSOR_2 > black){ //白のラインをトレースしている時 OnFwd(OUT_A);Off(OUT_C);ClearTimer(0); }else if(SENSOR_2 < black){ //黒のラインをトレースしている時 OnFwd(OUT_C);Off(OUT_A); } } Off(OUT_AC); //最後はロボットを停止させて終了する } //交差点で止まるサブルーチン sub corner_stop(){ ClearTimer(0); //最初にタイマーをリセットしておく while(FastTimer(0) < 63){ if(SENSOR_2 < black){ //白のラインをトレースしている時 OnFwd(OUT_C);Off(OUT_A);ClearTimer(0); }else if(SENSOR_2 > black){ //黒のラインをトレースしている時 OnFwd(OUT_A);Off(OUT_C); } } Off(OUT_AC); while(SENSOR_2 > black){ //黒のラインをトレースしている時 OnFwd(OUT_A);OnRev(OUT_C); } Off(OUT_AC); //最後はロボットを停止させて終了する } task main() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); FastTimer(0); ClearMessage(); intersection_stop_rightside(); //ヘアピンカーブで停止する corner_stop(); OnFwd(OUT_A);OnRev(OUT_C);Wait(180); //反転する SendMessage(OPEN); //アームを開けるメッセージを送信する OnFwd(OUT_AC);Wait(100); //ピンポンボールまで進む ClearMessage(); //アームを閉じる OnFwd(OUT_C);OnRev(OUT_A);Wait(130); //箱の正面まで回転 Off(OUT_AC); SendMessage(UP); //アームを上げるメッセージを送信する OnFwd(OUT_AC);Wait(100); //箱まで進む ClearMessage(); //アームを下げる SendMessage(OPEN); //アームを開くメッセージを送信する SendMessage(UP); //アームを上げるメッセージを送信する OnRev(OUT_AC);Wait(100); //箱から離れる Off(OUT_AC); ClearMessage(); //アームを下げる } **受信側 [#kdb95775] #define OPEN 13 //アームを開くメッセージの番号 #define UP 14 //アームを上げるメッセージの番号 #define FREEZE 15 //何もせず止まるようにするメッセージの番号 #define open(t) OnFwd(OUT_B);Wait(t);OnRev(OUT_B);Wait(5); //アームを開く番号 #define up(t) OnFwd(OUT_AC);Wait(t); //アームを上げる番号 task main() { ClearMessage(); while(true){ ClearMessage(); while(Message() == OPEN){ //OPENを受信したとき open(300); //3秒開く } Off(OUT_AC); //処理が終わったら停止 while(Message() == UP){ //UPを受信したとき up(300); //3秒開く } Off(OUT_AC); //処理が終わったら停止 } } *感想 [#u4973150] ロボットは小さくてバランスも良く、動いたときに~ ピンポンボールや箱に当たりにくくできてよかったと思った。~ しかし、ロボット2台を使って送受信を行うということもあり、~ プログラムに時間がかかった。~ 1台から2台に代わるだけで、プログラムがグンと難しくなったように感じた。~