[[2016a/Member]]

目次

#contents

*課題3について [#cbf535aa]
**ルール [#c514b484]
課題3は前回の課題で使用したコースを再利用し、C地点、D地点にある紙コップを交互に積み上げ、その積み上げた個数を競うものである。~
ロボットはそれぞれA地点、B地点からスタートし、一体型の場合はどちらか一方からスタートする。

**方針 [#u283e5b0]
今回は2台のキットを使い一体型のロボットを製作した。~
マスター側のハードに移動およびセンサー系関連、スレーブ側のハードにアーム関連(カップの積み上げ)のプログラムを入れておき、マスター側がスレーブ側のプログラムを呼び出しながら機体を動かすようにしている。


全体の流れを簡潔に示す。~
まずA地点からスタートし、C地点のカップを二つ確保する。そのあとD地点に向かい、カップを二つ確保し、これらのカップを交互に積み重ねる。最後に目的地点に重ねたカップを運ぶ、という流れである。~
なお、6つのカップを重ねることは、機体の構造を考えると非常に困難な動きになってしまうため、安定を求めて4つのカップを重ねることにしている。

*機体について [#z1b2728b]
**全体図 [#jd4e6d57]

&ref(image7.jpg);


&ref(image8.jpg);

上の2枚は機体の全体図と正面から撮った写真である。構造はクレーンを参考にして作ってある。~
従って、この機体には運転手がいる。写真1枚目で機体の左側に座っているレゴ君は車体の運転手をイメージしており(よって、写真1枚目左下方向がこの機体の正面である)、右側のレゴ君はクレーン部分の運転手をイメージして作ってある。~
因みに、機体正面には超音波センサーを設置してあるのだが、ブロックをYの字になるように組み合わせ、この部分にカップが入ると超音波センサーが感知するようにした。

**アームについて [#k3e10247]
&ref(image9.jpg);

写真でカップを4つほど保持しているアームをアーム1とし、写真中央付近にいるレゴ君が操縦している(とイメージしてほしい)アームをアーム2と名付ける。~
アーム2にはモーターが計3つ、それぞれ人間の肩にあたる根本の部分、人間の肘にあたる中間部分、人間の手にあたる先端部分についている。~
これらのモーターをそれぞれ独自に動かすことによって、カップを掴む、カップを持ったままアーム2を持ち上げる、カップを持ったままアーム2を回転させる、などといった行動を可能にしている。



*プログラムについて [#g97ee9e2]
**マスター側 [#d879496e]
  #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);  //カップとの距離が7.75cmになるまで近づく
   Off(OUT_AC);
   RemoteStartProgram(CONN,"cup_hold_first.rxe");  //カップをアーム2で掴み、アーム2を180度回転させ、アーム1の中に置き、アーム1で掴むプログラムを起動
   /* この時点でカップはアーム1に1個ある */
   Wait(10000);
   RotateMotor(OUT_B,30,-20);
   Wait(15000);
   RotateMotor(OUT_B,50,-28);
   OnRevSync(OUT_AC,50,0);
   until (SensorUS(S1) <= tyouonpa);  //カップとの距離が7.75cmになるまで近づく
   Off(OUT_AC);
   RemoteStartProgram(CONN,"cup_hold.rxe");  //カップをアーム2でつかんだままにしておくプログラムを起動
   /* この時点でカップはアーム1に1個、アーム2に1個ある */
   Wait(10000);
   RotateMotorEx(OUT_AC,75,500,100,true,false);  //方向転換
   RotateMotorEx(OUT_AC,75,-1500,0,false,false);  //C地点に向かう
   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);  //カップとの距離が7.75cmになるまで近づく
   until (SensorUS(S1) <= tyouonpa);    //カップとの距離が7.75cmになるまで近づく
   Off(OUT_AC);
   RemoteStartProgram(CONN,"cup_yoko_oki.rxe");  //アーム2で掴んでいるカップを機体の真横(進行方向とアーム2が垂直になるような位置)に置くプログラムを起動
   RemoteStartProgram(CONN,"cup_yoko_oki.rxe");    //アーム2で掴んでいるカップを機体の真横(進行方向とアーム2が垂直になるような位置)に置くプログラムを起動
   /* この時点でカップはアーム1に1個、機体の真横に1個ある */
   Wait(15000);
   RemoteStartProgram(CONN,"cup_hold_next.rxe");  //カップをアーム2でつかんで下ろすプログラムを起動
   /* この時点でカップはアーム1に2個、機体の真横に1個ある */
   Wait(20000);
   RemoteStartProgram(CONN,"cup_yoko_toru.rxe");  //機体の真横に置いてあるカップをアーム2で掴むプログラムを起動
   RemoteStartProgram(CONN,"cup_yoko_toru.rxe");    //機体の真横に置いてあるカップをアーム2で掴むプログラムを起動
   /* この時点でカップはアーム1に3個ある */
   Wait(20000);
   OnRevSync(OUT_AC,75,0);
   until (SensorUS(S1) <= tyouonpa);  //カップとの距離が7.75cmになるまで近づく
   until (SensorUS(S1) <= tyouonpa);    //カップとの距離が7.75cmになるまで近づく
   Off(OUT_AC);
   RemoteStartProgram(CONN,"cup_hold_next.rxe");  //カップをアーム2でつかんで下ろすプログラムを起動
   /* この時点でカップはアーム1に4個ある */
   Wait(20000);
   RotateMotor(OUT_A,75,180);  //方向転換
   RotateMotor(OUT_B,30,50);  //アーム1を開き、目標地点にカップを置く
 }

**スレーブ側 [#d00efd7a]
【cup_hold】:カップを持ち上げたままにしておくプログラムである。
 #define hold_upRotateMotor(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】:カップを持ち上げアーム1に運びアーム1の中に入れてから元の位置に戻るというプログラムである。
 #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); //手がマイナスで手を閉じる
    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); //手がマイナスで手を閉じる
    RotateMotor(OUT_A,75,-kata_hanten);    //手がマイナスで手を閉じる
    ResetTachoCount(OUT_ABC);
 }

【cup_yoko_oki】:カップを掴み、カップを機体の真横(アーム2が進行方向と垂直になるような位置)に置くプログラムである。
 #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); //手がマイナスで手を閉じる
    RotateMotor(OUT_A,75,-kata_hanten/2);    //手がマイナスで手を閉じる
    ResetTachoCount(OUT_ABC);
 }

【cup_yoko_toru】:【cup_yoko_oki】で横に置いたカップを取り、アーム1に運ぶプログラムである。
 #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  //肩の部分を半回転させるために必要なモーターの回転数
 #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_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);
 }

*結果 [#b4773096]
結果としては、超音波センサーが思うように作動しなかったことや試行回数の少なさなどが重なり、途中までしか機体を動かせなかった。

*反省とまとめ [#gc9b3e81]
まずなによりも時間が足りなかった。期末試験が近づいている時期だったこともあり皆集まれる時間が取れたのはロボコンの日の直前あたりからだった。~
機体の製作に特に時間を費やしたので、プログラムをあまり凝ったものにはできなかったが、その分見た目や動きで点数を稼ぐことができた。機体製作に特に尽力した班員のTomには頭が上がらない。~
今回は一体型の機体ということもあり、その重さからライントレースを行うのは困難であると判断し、移動はRotateMotorを用いて直線的な動きで構成したが、なかなか真っすぐ進んでくれなかった。原因は機体の重量やモーターの不備などが考えられる。~
非常に大変なゼミであったが、この講義を通じて、制御論の大切さ、ロボットを人のように動かすことの大変さを肌で感じることができ、とても良い経験になった。

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS