#contents *メンバー [#r15374e9] 飯島清貴 園部優花(自分) 柳澤曙太 横田翔真 *課題 [#h2252517] 課題2で使用したライントレースの紙を二枚つなげて、所定の位置に置かれた紙コップに入っているボールを交換するというものでした。詳しくは[[課題3:http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMission3]]を参照してください。 *ロボット [#d84b04cd] 今回のロボットの製作にはとても時間がかかりました。どのようにしてボールを取り出し、運んで、再び紙コップの中に入れるのかを自分たちで考えて、一から作らなければならなかったので大変でした。ロボットの製作はほとんど他のメンバーに任せてしまったのですが、頭の中にあるイメージを実際に形にしていく彼らはすごいと思いました。 ロボットの全体像はこちらです。 &ref(ロボコン1.jpg);&ref(ロボコン2.jpg); 私たちのチームはロボット前方のアームで紙コップを持ち上げ、ロボット上部に取り付けた格納庫に紙コップを傾けてボールをはじめに4個とも格納するというかたちにしました。そして格納したボールを二個ずつ落とし、再び紙コップに入れられるようにしました。このとき、格納庫にはボールが4個入っているため、何もしないと4個一気に落ちてしまうので、ボールを落とすアームが開くのと同時に3個目以降を落とさないようにストッパーが上がるように工夫しました。その部分が以下の写真です。 &ref(ロボコン4.jpg);&ref(ロボコン6.jpg); 本番で成功するところを私は見ることができませんでしたが、練習中にこの動きをやった時は高い確率で成功することができてうれしかったです。 *プログラム [#g1b501e6] はじめにメインのプログラムで使うプログラム等を定義しました。 #define CONN 1 #define SIGNALON 1 #define OPEN_SPEED 15 #define OPEN OnFwd(OUT_A,OPEN_SPEED);Wait(800);Off(OUT_A); #define CLOSE OnRev(OUT_A,OPEN_SPEED);Wait(1300);Off(OUT_A); #define SPEED_H 70 #define SPEED_L 50 const float diameter = 5.6; //タイヤの直径(�僉� const float track = 10.5; //タイヤのトレッド幅(�僉� const float pi = 3.1415; //円周率 float GetAngle_turn(float a) //求める本体の回転角からタイヤの回転角を求める関数 {float ang = (a*track)/diameter; return ang;} float GetAngle_go(float a) //求める移動距離からタイヤの回転角を求める関数 {float ang = a/(diameter*pi)*360.0; return ang;} sub angle_turn_L(float t) //左にt度回転 {int angle_turn_L = GetAngle_turn(t); RotateMotorEx(OUT_BC,SPEED_H,angle_turn_L,-100,true,true);//モータBとCをSPEED_Hで反転同期させて左にt度前転(ブレーキあり) Off(OUT_BC);} sub angle_turn_R(float t) //右にt度回転 {int angle_turn_R = GetAngle_turn(t); RotateMotorEx(OUT_BC,SPEED_H,angle_turn_R,100,true,true);//モータBとCをSPEED_Hで反転同期させて右にt度前転(ブレーキあり) Off(OUT_BC);} sub dist_go_F(float t) //前にtセンチ進む {int angle_go_F = GetAngle_go(t); RotateMotorEx(OUT_BC,SPEED_H,angle_go_F,0,true,true); Off(OUT_BC);} sub dist_go_R(float t) //後ろにtセンチ進む {int angle_go_R = GetAngle_go(t); RotateMotorEx(OUT_BC,-SPEED_H,angle_go_R,0,true,true); Off(OUT_BC);} ここからがメインプログラムです。今回は2台のNXTを通信させて行う課題だったので、まずはマスター側のプログラムです。 task main() {dist_go_F(57.0);//コップを取るボール搭載の信号を送る SendRemoteNumber(CONN, MAILBOX1, SIGNALON); Wait(9000);//スレーブ側のプログラムが終わるまで待つ angle_turn_R(150.0); dist_go_F(40.0);//コップを取るボール搭載の信号を送る SendRemoteNumber(CONN, MAILBOX1, SIGNALON); Wait(9000);//反転して dist_go_R(5.0); angle_turn_R(190.0); dist_go_R(20.0);//ボールを置く OPEN; Wait(1000); CLOSE; dist_go_F(50.0);//反転して dist_go_R(20.0); angle_turn_R(220.0);//コップまで近づく dist_go_R(33.0);//ボールを置く信号を送る OPEN; Wait(1000); CLOSE;//離れる dist_go_F(20.0);} 次は通信を受けるスレーブ側のプログラムです。コップを持ち上げてロボット上部の格納庫に入れる動作のプログラムになります。 #define SIGNALON 1 #define ARM_TIME1 1000 //アームの開閉時間1 #define ARM_TIME2 2000 //アームの開閉時間2 #define ARM_SPEED1 10 //アームの開閉スピード1 #define ARM_SPEED2 50 //アームの開閉スピード2 #define UP_TIME 2000 //アームを上げる時間 #define UP_SPEED 50 //アームを上げるスピード #define DOWN_TIME 1800 //アームを下げる時間 #define DOWN_SPEED 20 //アームを下げるスピード task main() {int msg; //受け取った値を格納する変数 while(true){ReceiveRemoteNumber(MAILBOX1, true, msg);//MAILBOX1の値を受け取りmsgに格納 if(msg==SIGNALON){ OnFwd(OUT_C,DOWN_SPEED);Wait(DOWN_TIME);Off(OUT_C);//アームを下げる OnRev(OUT_B,ARM_SPEED2);Wait(ARM_TIME2);Off(OUT_B);//アームを閉じる OnRev(OUT_C,UP_SPEED);OnRev(OUT_B,ARM_SPEED2);Wait(UP_TIME);Off(OUT_C);Off(OUT_B);//アームを上げる OnFwd(OUT_C,DOWN_SPEED);Wait(DOWN_TIME);Off(OUT_C);//アームを下げる OnFwd(OUT_B,ARM_SPEED1);Wait(ARM_TIME1);Off(OUT_B);//アームを開く ARM_UP2 OnRev(OUT_C,UP_SPEED);Wait(450);Off(OUT_C);//アームを定位置に戻す }else{Off(OUT_BC);} } } *反省と感想 [#jfa7e774] ロボットの組み立てに時間をかけてしまい、プログラムに費やせる時間があまりなくなってしまったため、納得したプログラムを作ることができませんでした。本来はロボットの前後に取り付けた距離センサーを使って紙コップまでたどり着くプログラムにしたかったのですが、ほとんど時間がない中でセンサーがうまく作動してくれなかったため、やむを得ず距離と角度を使ったプログラムに変えました。そのため微妙な誤差から思い描くような動きをしてくれず、最後まで成功するかわからないプログラムとなってしまいました。もっと早くから取りかかり、ロボット製作にもプログラムにも十分な時間をかけるべきだったというのが今回の一番の反省点です。それでも、このゼミを通してプログラムの難しさや自分でロボットを動かすことの楽しさを学べたので、来年以降に活かしていきたいと思います。