#contents *課題 [#e45e9125] http://yakushi.shinshu-u.ac.jp/robotics/?plugin=ref&page=2014b%2FMission3&src=robotics-2014b-3.png 紙コップに入っている赤ボール2個と青ボール2個を入れ替える。 ルールは[[課題3:http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMission3]]を参照 *メンバー [#gdcbb9a4] [[みっちゃん:http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMember%2FMisuzu%2FMission3]] [[ファンくん:http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMember%2FArisiaT%2FMission3]] [[山岸くん:http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMember%2FTomo%2FMission3]] *ロボット [#bb19cfe1] **ロボットの概要 [#hf1be0b8] 超音波センサで紙コップを探し、二つ横に並んだNXT横にとりつけて蟹のはさみのようなアームを操作することで、紙コップ内のボールを移動させます。 **最終型ロボット以前のロボット [#m80d9e14] 何度も改良に改良を重ねました。改良中のロボットはほとんどファンくんが作ってくれたので詳しくは[[ファンくんのページ:http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMember%2FArisiaT%2FMission3]]をご覧ください。 ***最終型以前の問題点 [#r7808e3b] 最終型以前のロボット写真 #ref(2014b/Member/maika/Mission3/ロボコン1.jpg,50%) 最終型以前のロボットの問題点は、 -不安定 -重過ぎてタイヤが潰れて斜め下方向に傾いてtしまう --モーター上に作った土台がしっかりしていない -四輪駆動にしたが、力を大きくかけないとしっかり旋回できない -アームの接続が不安定 --アームの取り付けを安定したものにするため、二台のNXTの上を渡るようにして固定したが、それによって画面がまったく見えなくなってしまう。 というものがありました。 **最終型ロボット [#ne2dc7a6] 最終型ロボット写真 #ref(2014b/Member/maika/Mission3/ロボコン7.jpg,70%) 先生の協力のもとモータ上に作った土台が安定したものになりました。そのおかげで、以前重さに耐えきれないということでつけられなかったキャスターを難なく取り付けることができ、四輪駆動による小回りの悪さも解決しました。 二台のNXTの通信を音とBluetoothで行うため、スピーカーのすぐ近くにサウンドセンサをとりつけました。 #ref(2014b/Member/maika/Mission3/ロボコン6.jpg,70%) また、モータによる開け閉めが可能な蓋を取り付けても移動が可能な蓋をとりつけることでコップを真上に持ち上げたままでも移動することが可能になりました。また、垂直にボールを注ぐことができるので、より正確にボールを注ぐことができると考えました。 #ref(2014b/Member/maika/Mission3/ロボコン4.jpg,40%) 画面が見えないという問題も、上のようにブロックでレールを作ることで、多少は画面に被るもののはるかに画面を見やすくすることができました。アームも、重さで下に落ち込むことがなくなり、安定性がかなり向上しました。 *プログラム [#i2813d40] **定義 [#kc2b16ac] #define SPEED 70 #define SPEED_SLOW 45 #define CONN 1 //スレーブの接続番号 -二台のNXTによるBluetooth通信をするために、スレーブの番号を指定しました。 -この、SPEED_SLOWはアームがボールの入った紙コップを掴みに旋回する時、紙コップを倒さないかつ、旋回する時タイヤが紙面にひっかからないスピードになるよう工夫しました。 **超音波センサを使って紙コップを探すプログラム [#q82beec8] const float diameter = 5.45; //タイヤの直径(cm) const float track = 12; //タイヤのトレッド幅(cm) const float pi = 3.1415; //円周率 void fwdDist(float d) //距離dcm前進 { long angle; angle = d/(diameter*pi)*360.0; //角度を計算する RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 0, true, true); } void turnAng(long ang) //角度ang度の時計回りの旋回 { long angle; angle = track/diameter * ang; RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 100, true, true); } void ReturnAng(long ang) //角度ang度の半時計回りの旋回 { Wait(500); long angle; angle = track/diameter * ang; RotateMotorEx(OUT_BC, SPEED_SLOW, angle, -100, true, true); } int searchDirection(long ang) //現在の方向を中心にang度の範囲で探し、障害物までの距離を返す { long angle,tacho_min=0, tacho_corr; int d_min; d_min=600; //仮の最小値 angle = (track/diameter)*ang; //旋回角度からタイヤの回転を計算 turnAng(ang/2); //指定された角度の半分を旋回 ResetTachoCount(OUT_BC); //角度計測をリセット OnFwdSync(OUT_BC,SPEED_SLOW-15,-100); //半時計回りに旋回 while(MotorTachoCount(OUT_B)<=angle){ if(SensorUS(S1)<d_min){ d_min=SensorUS(S1); tacho_min=MotorTachoCount(OUT_B); } } OnFwdSyncEx(OUT_BC,SPEED_SLOW,100,RESET_NONE); until(MotorTachoCount(OUT_B)<=tacho_min||SensorUS(S1)<=d_min); Wait(14); //微調整 Off(OUT_BC);Wait(500); return d_min; } -サンプルのプログラムをそのまま使いました。 -また、 long angle save や angle_save=tacho_min; を使い、 void comeback(int d, int cm, int turn, int angle){ ReturnAng(angle); fwdDist(-d); turnAng(turn); } というサブルーチンを使うことで、ロボット本体の移動した道順を記憶をし、それを逆再生することで、運んだ紙コップをもとの位置に戻したり、二枚目の紙に移動したりしようとしたのですが、うまくいきませんでした。 -コップを探し、aセンチメートル手前で停止し、b度回転する動作を void SearchCup(int a, int b)//a=何cm手前で停止、b=行って何度回転する {int d = searchDirection(60); if (d > a) { fwdDist(d-a); } Wait(100); ReturnAng(b); //反時計周りにb度旋回 Off(OUT_BC); } というサブルーチンで行います。 **二台のNXTの通信 [#i7bbeec0] 当初、二台のNXTの連携をBluetoothのみを使って行おうとしていました。 が、プログラムのミスでうまくマスターとスレーブ間でメッセージの送受信ができませんでした。 そこで、マスターがスレーブにあるプログラムの起動をBluetoothを介して命令し、そのプログラムの実行後スレーブから発せられる音をマスター側のサウンドセンサが感知することで、マスターがそのプログラムの終了を認識するという、音とBluetoothを使って通信をするようにしました。 サウンドセンサがスレーブの発した音感知するまで、マスター側が待機するプログラムを以下のサブルーチンで定義します。 void WAIT(){ while(Sensor(S2)>99)//返事(音)を待つ {Wait(1);} } **プログラム本体 [#u85c7343] #ref(2014b/Member/maika/Mission3/ロボティクス入門5.jpg,50%) ボールの入ったコップを掴んだ後、超音波センサで空のコップを探すまでロボットは上図の赤線を辿っていきます。 task main() { SetSensorLowspeed(S1); //端子1に超音波センサ SetSensorSound(S2); //端子2に音のセンサ まず、ロボットを後ろ向きに置いて、 fwdDist(-40.0); //50センチ後退 Wait(500); ReturnAng(70); //反時計周りに70度旋回 Wait(500); fwdDist(25.0); //30センチ前進 Wait(500); 紙コップの位置を探すプログラムであるSurchCupを始める位置(上図赤丸1)へ移動します。 /*ボールの入ったコップの方向を探した後、近づいて8センチ手前で停止し、70度回転*/ SearchCup(8,70); このプログラムでコップに近づいた後、スレーブと連携してコップを掴みます。 コップを掴む前に、ロボット本体を70度回転させることでしっかりアームのはさみの中にコップをおさめ、図の☆の位置でコップを掴みます。 スレーブの、 hold_sound.rxeはコップを掴むプログラムです。 スレーブのプログラムは全て山岸くんが担当したのでそちらをご覧下さい。 until(BluetoothStatus(CONN)==NO_ERR); //接続できるまで待つ /*コップに近づいた後スレーブコップをつかむプログラムを送信*/ RemoteStartProgram(CONN,"hold_sound.rxe"); WAIT();//スレーブが音を発するまで待つ スレーブのプログラムが終了した後、次に超音波センサでコップを探す位置(図中赤丸2)へ移動し、空のコップを探します。 ReturnAng(130); //反時計周り130度旋回 Wait(500); fwdDist(-15); //10cm後退(図中青線) /*空のコップの方向を探した後、近づいて11センチ手前で停止*/ SearchCup(11,0); コップに近づいた後、空にコップにボールを注ぎます。 スレーブ側で、 pour_up.rxe pour_open.rxe pour_down.rxe をそれぞれ起動させます。 pour.upは、アーム部に付けたブロックでボールが下に零れないよう蓋をした後、掴んでいるコップを真上に持ち上げるプログラムです。 ロボット本体を反時計回りに40度旋回させ持ち上げたコップが空のコップの真上にくるよう微調整した後、pour_open.rxeという蓋をあけるプログラムを起動させ、ボールを空のコップに注ぎます。 その一連の動が以下のプログラムになります。 /*空のコップに近づいた後スレーブにボールを注ぐプログラムを送信*/ RemoteStartProgram(CONN,"pour_up.rxe"); Wait(5000); RemoteStartProgram(CONN,"pour_open.rxe"); Wait(3000); turnAng(-40); RemoteStartProgram(CONN,"pour_down.rxe"); Wait(3000); 注ぎ終わったら、掴んでいるコップをもとの位置に戻します。 注いだコップを倒さないように移動するよう工夫しました。 fwdDist(-20); //20センチ後退 Wait(500); ReturnAng(120); //120度反時計回りに旋回 注ぎ終わったら、掴んでいるコップをもとの位置に戻します。 注いだコップを倒さないように移動するよう工夫しました。 コップを話した後、 fwdDist(-20); //20センチ後退 Wait(500); ReturnAng(120); //120度反時計回りに旋回 Wait(500); /*スレーブにコップを離すプログラムを送信*/ RemoteStartProgram(CONN,"release_sound.rxe"); WAIT(); コップを離した後、もう一枚の紙に移動します。 turnAng(90); //時計回りに90度旋回 fwdDist(-25); //25センチ後退 Wait(500); turnAng(-70); //反時計回りに70度 Wait(500); fwdDist(30); //30センチ前進 ここから図の赤丸1からのプログラムと同じことを繰り返します。 *反省点 [#b4877ca2] -ボールをきちんと注げるのが三回に一度程度という非常に精度にかけるものになってしまいました。 --紙コップとの距離が毎回同じ距離のところでロボットが停止しなければならないのでそこを改良したい。 -土台をもっとしっかりしたものにしなかったがために、何度もロボットを改良したり、一日前になって解体しなければならないということになってしまったので、ベースの部分はもっと早い段階で完璧にしておくべきだった。 -二枚目のフィールドに移動した後は一枚目のプログラムと同じことを繰り返せばいいと思ったのだが、ボールの入ったコップをはさみがきちんとつかんでくれないという事態が起こってしまった。本番でこれが起こってしまったため、全く対処できずに終わってしまったので、もっと事前練習しておきたかった。 --紙コップとの距離が毎回同じ距離のところでロボットが停止しなければならないのでそこを改良したいです。 -土台をもっとしっかりしたものにしなかったがために、何度もロボットを改良したり、一日前になって解体しなければならないということになってしまったので、ベースの部分はもっと早い段階で完璧にしておくべきでした。 -二枚目のフィールドに移動した後は一枚目のプログラムと同じことを繰り返せばいいと思ったのですが、ボールの入ったコップをはさみがきちんとつかんでくれないという事態が起こってしまいました。本番直前で繰り返しのプログラムをコピペしたので、原因がわからず終わってしまいました。プログラムの完成、もっと言えば、本体の完成を急ぐべきでした。 -ブロックとアーム側のNXTとをピンでしっかり接続せず、アームの重さに頼ってしまいました。そこの接続をもっと強いものにしてアームの安定化ができればさらに良いロボットになったと思います。