[[2017b/Member]]
目次
#contents
*概要 [#xb3bd784]
今回の課題3は課題2で使用した紙を使用し、コップの中にあるピンポン玉を指定の場所まで運ぶというものであった。下の図を用いて簡単に説明すると、明るいワイン色に置いてあるコップの中にあるピンポン玉を割りばしで囲まれたX地点まで運びコップはY地点の円の中に運ぶという感じである。それ以外の詳しい事は[[課題3:http://yakushi.shinshu-u.ac.jp/robotics/?2017b%2FMission3]]を参照してほしい。左上のものが一番取りやすそうということで自分たちのチームはA地点から出発することにした。
#ref(./2017b-mission3.png,320x240,コースの全体)
*機体 [#vc83f382]
**試作1号機 [#yf03ac6c]
1号機は本体を横に並べて取り付けその下にタイヤを動かすためのモータを二つ取り付けた。また前方には光センサーと超音波センサーを取り付けた。光センサーは課題2の経験を活かし地面すれすれに取り付けることによってロボットが動く際の振動による誤差を減らした。また、超音波センサーは先生のアドバイスを基に縦にすることでコップの位置を詳細に図ることができようにした。次にアームはコップを上げたり下げたりするモータとコップを掴むモータとの二つのモーターを使用した。掴む機構としては先に付いているアームでコップを掴み下の写真の赤く囲まれた出っ張りにコップを引っ掛け掴むというものであった。そしてもう一つのモータでコップを上げる。しかしこの機構には問題が数多くあり、一番の問題はあまりにもコップを掴むことが難しいということだ。つまりコップを盾に掴むので掴む幅が小さくなるためコップの位置が正確でかつロボットが毎回同じ位置に移動しなければコップを掴めないということだ。もし1cmでもズレた場合には全く何の役割を果たさなくなる。また、コップが毎回出っ張りに引っかかるとは限らないのでこれでは一つもコップを掴めない恐れがあるためこの試作機は失敗になった。
#ref(./DSC_0416.JPG,320x240,試作1号機)
**試作2号機 [#l6ccfb91]
2号機は1号機とはコップを掴む機構を改良したロボットにした。具体的には1号機の掴む機構は縦なのに対して2号機の掴む機構はクワガタのように横にした。このことによりある程度コップの位置がずれたり、ロボットの位置が多少ズレた場合でもコップを掴めることが出来るようになった。機構としては歯車を三個使用した。仕組みはまず写真にある一番右の歯車がモーターと繋がっており、真中の歯車が右のアーム、一番左の歯車が左のアームにつながっており、それぞれの上下に同じレゴで固定した。また、モーターの設置はコップを持ち上げるモーターが下がった後少し上に傾くようにした。このことでコップを掴みその後コップを運びその後ピンポン玉を割りばしの中に入れる際にコップが割りばしにあたりピンポン玉が入らなくなるのを防ぐためだ。

&ref(2017b/Member/yuu/Mission3/DSC_0420.JPG,320x240,2号機 掴む機構);
&ref(2017b/Member/yuu/Mission3/1518422316830.jpg,320x240,2号機 斜めになっている様子);

また、後ろのタイヤはタイヤのままでは摩擦があり、場合によってはロボットの重さで後輪だけが動かなく事例が発生したためタイヤのゴムの部分を取り除きホイールだけにした。このことで摩擦が減り、後ろの車輪が動くようになった。

&ref(2017b/Member/yuu/Mission3/DSC_0425.JPG,320x240,2号機 後輪部分);

**改善点 [#w0104ff7]
試作1号機と2号機を比べるとはるかに2号機の方が完成形としては近かったが2号機にも問題があった。一つ目はロボットが縦になりすぎていたことだ。あまりにも長すぎると途中の障害物に当たる可能性も大きくなる。二つ目は重心が後ろにあまりにも後ろに集中しすぎていたことだ。重心が後ろに集中していたため後輪が動かないということが起こった。2号機は多少は改善されてはいたが完全とは言えないものであった。これらのことを考慮すると本体を横に並べてつなげるのではなく上下に付けて設置するべきであった。また、設置する箇所は後ろではなくタイヤの間などの真中に取り付け本体とモーターの間付近にコップを回収するためのモーターを設置するべきであった。
*プログラム [#lb617286]
**マスター側 [#w9efb64c]
***define [#r3096f7a]
 #define SPEED 55
 #define SPEED_SLOW 45
 #define SPEED_CURVE 45
 #define SPEED_FAST 55
 #define THRESHOLD 38
 #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL);
 #define go_forward OnRL(SPEED_FAST,SPEED_FAST);
 #define turn_right_high OnRL(-30,SPEED_CURVE);
 #define turn_right_low OnRL (0,SPEED_CURVE);
 #define turn_left_high OnRL(SPEED_CURVE,-30);
 #define turn_left_low OnRL (SPEED_CURVE,0);
 #define CONN 1   
 #define SIGNAL_CATCH 11   
 #define SIGNAL_RELEASE 12   
 #define SIGNAL_UP 13 
 #define SIGNAL_UP1 14  
 #define SIGNAL_DOWN 15
***コップ回収のためのプログラム [#vbc63e7c]
 const float diameter = 5.45;    //タイヤの直径。NXTのタイヤの直径は約5,45cmのためこの値。
 const float track = 10.35;    //タイヤのトレッド幅。トレッドとはタイヤの中心間距離。
 const float pi = 3.1415;         //円周率。

 void fwdDist(float d)      //距離dcm進ためのプログラム。
 {
    long angle = d/(diameter*pi)*360.0;       //進むのに必要なタイヤの回転角を計算。
    RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 0, true, true);
 }

 void turnAng(long ang)          //角度ang度の時計回りの旋回するためのプログラム。
 {
   long angle = track/diameter * ang;       //進むのに必要な回転角度を計算。
    RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 100, true,true);
 }

 int searchDirection(long ang)                //現地点を中心として角度ang度の範囲内で回転してコップを探しコップまでの距離を測る。
 {
    long tacho_min;
    int d_min = 300;
    long angle = (track/diameter)*ang;
    turnAng(ang/2);
    ResetTachoCount(OUT_BC);
    OnFwdSync(OUT_BC,SPEED_SLOW,-100);
    while(MotorTachoCount(OUT_B)<=angle){
     if(SensorUS(S3)<d_min){
      d_min = SensorUS(S3);
      tacho_min = MotorTachoCount(OUT_B);
      }
     }
    OnFwdSyncEx(OUT_BC,SPEED_SLOW,100,RESET_NONE);
    until(MotorTachoCount(OUT_B)<=tacho_min || SensorUS(S3)<=d_min);
    Wait(14);
    Off(OUT_BC);
    Wait(500);
    return d_min;
 }
***メインプログラム [#pca44767]
 task main()
 {
    SetSensorLight(S2);
    RotateMotor(OUT_BC,35,315);
    Wait(1000);
    RotateMotor(OUT_BC,35,320);
    Wait(1000);
    SendRemoteNumber(CONN,MAILBOX1,SIGNAL_CATCH);   //スレーブ側にコップを回収するための信号を送る。
    Wait(2000);    //何秒か待たないとそのままプログラムが進行されるので3秒間待つことにした。
    Wait(1000);
    RotateMotor(OUT_C,55,180);
    RotateMotor(OUT_B,-55,310);
    Wait(1000);
    RotateMotor(OUT_BC,35,260);
    SendRemoteNumber(CONN,MAILBOX1,SIGNAL_UP);      //スレーブ側にアームを上げるための信号を送る。
     Wait(2000);
    RotateMotor(OUT_C,-55,360);
    RotateMotor(OUT_BC,55,600);
    RotateMotor(OUT_B,-55,330);
    RotateMotor(OUT_C,55,50);
    RotateMotor(OUT_BC,55,900);
    SendRemoteNumber(CONN,MAILBOX1,SIGNAL_DOWN);   //スレーブ側にアームを下げるための信号を送る。
     Wait(1500);
    SendRemoteNumber(CONN,MAILBOX1,SIGNAL_RELEASE);   //スレーブ側にコップを離すための信号を送る。
    Wait(2000);
    SendRemoteNumber(CONN,MAILBOX1,SIGNAL_UP);    
    Wait(2000);
    RotateMotor(OUT_BC,-55,100);
    OnFwd(OUT_B,55);
    OnFwd(OUT_C,55);
    Wait(1000);
    Off(OUT_BC);
    SetSensorLowspeed(S3);
     int d = searchDirection(60);
    if (d > 5){              //コップの手前5cmで止まる。
       fwdDist(d-5.0);
      }
 }
**スレーブ側 [#cf3d35f2]
***define [#ec27d41e]
 #define SIGNAL_CATCH 11   
 #define SIGNAL_RELEASE 12   
 #define SIGNAL_UP 13   
 #define SIGNAL_UP1 14  
 #define SIGNAL_DOWN 15
***メインプログラム [#v3995d22]
 task main()
 {
    int msg;
    while(true){
    ReceiveRemoteNumber(MAILBOX1,true,msg);
    if (msg == SIGNAL_CATCH) {
        OnFwd(OUT_C,40);         //RotateMotorでは途中動かなくなりそこでプログラムが中断する場合があったためWaitを入れたものを作った。
         Wait(800);
         Off(OUT_C);
      }else{
     if (msg == SIGNAL_RELEASE) {
        RotateMotor(OUT_C,-20,38);
       }else if 
      (msg == SIGNAL_UP) {
         RotateMotor(OUT_B,-45,120);
      }else if
       (msg == SIGNAL_DOWN) {
       RotateMotor(OUT_B,45,94);
     }else if
        (msg == SIGNAL_UP1) {
        OnFwd(OUT_B,-50);
         Wait(1000);         
         Off(OUT_B);
    }
 }
 }
 }
*感想 [#a4ce1cb9]

今回は制作時間が短いかかったためいろいろと問題点が多かった。中でもロボットの重心が後ろの方に集中していることが最も改善するべき点であった。発表会本番では1回目2回目ともにコップを回収できずに終わることになったが最後に再度行うとコップを回収してピンポン玉も運ぶことが出来、またコップも指定の場所まで運ぶことが出来た。しかし、制作時間の都合上コップは1個しか運ぶことが出来ないプログラミングであったため点数は低くなってしまった。したがってもし次があるならば重心の位置を念頭に置き、確実性を高めたロボットやプログラミングを組む必要がある。

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