*はじめに [#h91c573f] *課題 [#w6c81c03] **ルール [#h863a473] ルールはC地点、D地点にある紙コップを交互に積み上げ、その積み上げた個数を競うものである。コースは下図の通り課題2のコースを使う。 ロボットはA地点B地点からスタートし、一体型の場合はどちらかからスタートする。 2機が通信して協力し合い、課題をいかに早くクリアするかを競うものである。 #ref() **方針 [#o8b80ded] 今回の課題はルール上、NXT一機につきモーターが3つという制限ではクリアはきつかった。よって一体型を作ることにした。 一体を移動とセンサ系、もう一体をカップの積み上げという作業の分担を行わせる。また、片方に主眼を置いてプログラムうを組むことで、通信を行わせるという課題をクリアするとともに全体の流れを把握しやすくなることを狙った。 流れとしてはスタート地点から近い方のカップに向かう。その後、C地点とD地点の間を往復しカップを積み上げる。その間、積み上げたカップは機体で保持するようにする。 最後にゴールにカップを置いて終了とする。 ざっくりとだが以上である。 **ハードウェアについて [#o62a0bc5] ハードは上記の方針より、以下の4つの能力が必要となる。 ・カップを掴む ・カップを積み上げる ・積み上げられたカップを保持すること ・積み上げられたカップを崩すことなく下すこと これらを満たすハードウェアとして複数の関節を持ったアームのような機構とカップを保持するためだけの機構を作った。 **ソフトウェアについて [#xef5442d] *それぞれの機構について [#cbfe4a86] **アーム部分 [#d61ccf92] アーム部分はカップを持ち上げる動作、積み上げる動作を担う部分である。よってクレーンを参考として腕のような機構を作った。(下画像) #ref() 下はカップを掴んでいる写真 順に説明する。 ***手に当たる先端部分について。 [#xa47dbf9] これは下の画像のように隣接する歯車は逆に回転していることを利用した。 #ref() プログラムは下記の通りである。モーターの回転角度が小さくてすむため回転角度を指定する命令を利用した。使用回数が多いため、ほとんどは定義部分にのみ入れている。 RotateMotor(OUT_B,50,-88); //手閉じる RotateMotor(OUT_B,50,88); //手開く また、先端にてモーターが腕の部分と垂直になっているのはバランスを保つためである。今回は紙コップを掴む競技であったためゴムによる滑り止めと紙コップの淵による引っかかりでより安定する持ち方となっている。しかし、モーターの形や掴む対象の形しだいでは、手の取り付けをもう一工夫する必要がある。 ***肘に当たる中間部分について [#p0fcc65a] 肘の部分は普通に考えればモーターの回転する部分に長い棒を固定して回せば良い。 しかしこの機器の場合、手の重さとモーターの力不足によりそれではアームが壊れる可能性が強くなってしまう。 よってこの機体では下の画像のようにギア比による出力不足の改善を行った。大きい歯車が2つ付いているのは腕の補強のために力のかかる場所を分散させるためである。 ***肩に当たる根元部分について [#l7f28ef1] **マスター側 [#p63f092f] #define CONN 1 // スレーブの接続番号 #define tyouonpa 7.75 task main() { SetSensorLowspeed(S1); RotateMotorEx(OUT_AC,75,-600,0,true,true); //AからDへと向かう Wait(2000); until (BluetoothStatus(CONN) == NO_ERR); // 接続できるまで待つ OnRevSync(OUT_AC,50,0); until (SensorUS(S1) <= tyouonpa); //8cmまで近づく Off(OUT_AC); RemoteStartProgram(CONN,"cup_hold_first.rxe"); //コップをつかんで下ろすプログラムを起動 Wait(10000); RotateMotor(OUT_B,30,-20); Wait(15000); RotateMotor(OUT_B,50,-28); OnRevSync(OUT_AC,50,0); until (SensorUS(S1) <= tyouonpa); //8cmまで近づく Off(OUT_AC); RemoteStartProgram(CONN,"cup_hold.rxe"); //コップをつかんだままのプログラムを起動 Wait(10000); RotateMotorEx(OUT_AC,75,500,100,true,false); //方向転換 RotateMotorEx(OUT_AC,75,-1500,0,false,false); //Cに向かう OnRevSync(OUT_AC,75,0); until (SensorUS(S1) <= tyouonpa); //7cmまで近づく Off(OUT_AC); RemoteStartProgram(CONN,"cup_yoko_oki.rxe"); Wait(15000); RemoteStartProgram(CONN,"cup_hold_next.rxe"); //コップをつかんで下ろすプログラムを起動 Wait(20000); RemoteStartProgram(CONN,"cup_yoko_toru.rxe"); Wait(20000); OnRevSync(OUT_AC,75,0); until (SensorUS(S1) <= tyouonpa); //7cmまで近づく Off(OUT_AC); RemoteStartProgram(CONN,"cup_hold_next.rxe"); //コップをつかんで下ろすプログラムを起動 Wait(20000); RotateMotor(OUT_A,75,180); //方向転換 RotateMotor(OUT_B,30,50); //アームを開く } **スレーブ側 [#f8ac4253] 【cup_hold】 #define hold_up RotateMotor(OUT_C,50,500); Wait(1000); RotateMotor(OUT_B,50,-88); RotateMotor(OUT_C,80,-500); #define hold_down RotateMotor(OUT_C,50,500); Wait(1000); RotateMotor(OUT_B,50,88); RotateMotor(OUT_C,80,-500); task main() { ResetTachoCount(OUT_ABC); hold_up; //手(先端)がモータB 肘(中間)がモータC 肩(根本)がモータA Off(OUT_B); } 【cup_hold_first】 #define hold_up RotateMotor(OUT_C,50,500); Wait(1000); RotateMotor(OUT_B,50,-88); RotateMotor(OUT_C,80,-500); #define hold_down RotateMotor(OUT_C,50,500); Wait(1000); RotateMotor(OUT_B,50,88); RotateMotor(OUT_C,80,-500); #define kata_hanten 860 task main() { ResetTachoCount(OUT_ABC); hold_up; //手(先端)がモータB 肘(中間)がモータC 肩(根本)がモータA RotateMotor(OUT_C,90,-100); Off(OUT_B); Wait(2000); RotateMotor(OUT_A,75,kata_hanten); //肩180度回転(正で正面右) Wait(1500); RotateMotor(OUT_C,75,100); hold_down; RotateMotor(OUT_A,75,-kata_hanten); //手がマイナスで手を閉じる ResetTachoCount(OUT_ABC); } 【cup_hold_next】 #define hold_up RotateMotor(OUT_C,50,540); Wait(1500); RotateMotor(OUT_B,50,-88); RotateMotor(OUT_C,80,-540); #define hold_down RotateMotor(OUT_C,50,450); Wait(1500); RotateMotor(OUT_B,50,88); RotateMotor(OUT_C,80,-450); #define kata_hanten 860 task main() { ResetTachoCount(OUT_ABC); hold_up; //手(先端)がモータB 肘(中間)がモータC 肩(根本)がモータA RotateMotor(OUT_C,90,-100); RotateMotor(OUT_B,80,-3); Off(OUT_B); Wait(2000); RotateMotor(OUT_A,75,kata_hanten); //肩180度回転(正で正面右) RotateMotor(OUT_C,50,50); Wait(2000); hold_down; RotateMotor(OUT_C,50,50); RotateMotor(OUT_B,80,3); RotateMotor(OUT_A,75,-kata_hanten); //手がマイナスで手を閉じる ResetTachoCount(OUT_ABC); } 【cup_yoko_oki】 #define hold_up RotateMotor(OUT_C,50,540); Wait(1000); RotateMotor(OUT_B,50,-88); RotateMotor(OUT_C,80,-540); #define hold_down RotateMotor(OUT_C,50,500); Wait(1000); RotateMotor(OUT_B,50,88); RotateMotor(OUT_C,80,-500); #define kata_hanten 860 task main() { ResetTachoCount(OUT_ABC); //手(先端)がモータB 肘(中間)がモータC 肩(根本)がモータA RotateMotor(OUT_A,75,kata_hanten/2); //肩90度回転(正で正面右) Wait(1500); hold_down; RotateMotor(OUT_A,75,-kata_hanten/2); //手がマイナスで手を閉じる ResetTachoCount(OUT_ABC); } 【cup_yoko_toru】 #define hold_up RotateMotor(OUT_C,50,540); Wait(1000); RotateMotor(OUT_B,50,-88); RotateMotor(OUT_C,80,-540); #define hold_down RotateMotor(OUT_C,50,500); Wait(1000); RotateMotor(OUT_B,50,88); RotateMotor(OUT_C,80,-500); #define kata_hanten 860 task main() { ResetTachoCount(OUT_ABC); //手(先端)がモータB 肘(中間)がモータC 肩(根本)がモータA RotateMotor(OUT_A,75,kata_hanten/2); //肩90度回転(正で正面右) Wait(1000); hold_up; RotateMotor(OUT_C,90,-100); RotateMotor(OUT_B,80,-5); Off(OUT_B); Wait(2000); RotateMotor(OUT_A,75,kata_hanten/2); //手がマイナスで手を閉じる RotateMotor(OUT_C,50,50); Wait(1000); hold_down; RotateMotor(OUT_C,50,50); RotateMotor(OUT_A,75,-kata_hanten); ResetTachoCount(OUT_ABC); } *結果と考察 [#c834bed8] *感想 [#wa2f1a3d]