[[2015a/MemberOnly]] *目次 [#e57e1c21] &ref(./ライントレース 移動中.JPG,15%); #contents *課題 [#qd7d1866] &ref(./2015a-mission2 コース.png,50%); ロボットのセンサーを利用して、図の「B」の地点から「A」の地点まで ロボットの光センサーを利用して、図の「B」の地点から「A」の地点まで 黒線を追いながら移動するライントレース。 途中球をキャッチして最後、Aに設置してあるゴールに球をシュートする。 *全体の流れ(問題へのアプローチの仕方) [#w1d518f3] &ref(./2015a-mission2 コース 改.png,50%); 通常の直線、曲線では黒線と白紙の境界を行き来するプログラムによって移動するが、それでは越えられない問題のあった3つの難所についてはカウンターを用いて識別し、それぞれ別の方法で移動するように過程を分けることで進ませようとした。 **�…廠僖�ーブ [#t68930cc] 直線カーブは通常の動作では黒線を認識出来なくなり見当違いの方向に進んだり、ひどいときは逆走してしまったりした。そこで、 **�…廠僖�ーブ [#x1463652] 黒線よりの境界を行き来するようにして極力 1.白の検出回数の変数を定義する。 2.一定数以上の白の判定を出したら小さく前進する。 3.黒の判定が出るまでその場で反時計回りの旋回をする。 4.方向転換が完了し、また通常のライントレースを開始する。 という、一連の動作を行うプログラミングを組むことで問題を解決することが出来た。 **�↓8鮑硬性�,�� [#y8fdc4f1] この課題における最大の難所、まっすぐに進まねばならないが通常の移動のプログラムでは進めずかつ専用のプログラムを用いたら通常のカーブを誤認識して失敗してしまう。そこで、 1.�,僚�了後から専用プログラムに切り替える。 2.交差点�兇鯆眠瓩靴晋紂△泙芯名錣琉榮哀廛蹈哀薀爐棒擇蠡悗┐襦� これによって専用プログラムを用いる範囲を限定し、誤作動をおこしにくくした。また、変数を用いることで簡単に1回目のみに球をつかむ動作を入れることが出来た。 **�ぅ轡紂璽� [#gca06aca] 最後に球を白い部分に至るまえの直線からゴールに向けてシュートする。最後は特徴のないが直線伸びているだけなので、ラインの判断ではなくタイマーを利用した。 交差点を終えた部分からは通常のカーブと直線だけなので交差点終了後にタイマーを起動することで正確に起動するようになった。 *ロボット及び制作の過程 [#i59ca00c] &ref(./全体 横から.JPG,10%);&ref(./裏返し センサー.JPG,10%); ロボットの作成は付属の説明書にあるライントレーサーにセンサーとモーターの距離を近くしてより正確に動くように改良を施し、アームを取り付けるための改造を施した。 ロボットの作成は付属の説明書にあるライントレーサーにセンサーとモーターの距離を近くしてより正確に動くように改良を施し、アームを取り付けるための改造を施した。後ろに主機、モーター2つが集まっているため後方に重さが偏っている問題がある。これは走行に影響があるほどではなかったのでそのままにしたが前輪の固定が足りずたまに外れてしまう問題があった。この原因はパーツ不足だが後輪の動きが良く、頻度も低かったので放置した。 **アーム [#w7993c82] &ref(./正面からのアーム.JPG,10%); &ref(./正面からのアーム.JPG,10%);&ref(./アーム解説用.JPG,10%); クワガタの顎のような形のアーム。もっとも苦労したのはこのアームの取り付けで主機を付け変え、そのスペースにモーターを入れて前に出すぎず固定できた。 このアームの利点はギアの噛み合わせがしっかりとしていて安定していることと、大きくはさみこむため少々ずれたとしても問題なく動作することである。 このアームの利点はギアの噛み合わせがしっかりとしていて安定していることと、大きくはさみこむため少々ずれたとしても問題なく動作すること、縦に幅を持たせて球がすり抜けないようになっている事である。 **後輪 [#d278c316] &ref(./IMG_0448.JPG,10%); さまざまな方向に移動する主機の移動についていくための後輪。360度回転でき、どんな移動に対しても動作する事が出来る。 さまざまな方向に移動する主機の移動についていくための後輪。360度回転でき、どんな移動に対しても動作する事が出来る。難点としては特定のパーツを使いすぎ前輪不安定につながった点。 *プログラム [#cb158d88] 様々な問題そして解決のための方法も多様化したため前回と比べ物にならない複雑さとなった。全体としてはサンプルの交差点を渡るプログラムを参考にしつつ、全体を �…廠僖�ーブまで ��2つの交差点を通りすぎるまで ��交差点�気泙� ��最後の曲線からシュートまで �8鮑硬性兇泙� �ず埜紊龍弊�からシュートまで の3つのセクションに分けて取り組んだ。 **定義 [#f55ebb2a] 長いプログラムとなったため以下のような多くの定義を用いた。 #define Lblack 30 //暗い黒 #define Sblack 38//薄い黒 #define Lwhite 60 //明るい白 #define Swhite 52 //暗めな白 #define SPEED_ST 40//直線での速度 #define SPEED_CR 25//曲線での速度 #define OnRL(sR,sL) OnFwd(OUT_B,sR);OnFwd(OUT_C,sL); //左速度sL、右速度sRでの移動 #define go_ST OnRL(SPEED_ST,SPEED_ST); //直進 #define turn_L0 OnRL(SPEED_CR,0);//左折 #define turn_L1 OnRL(SPEED_CR,-SPEED_CR); //左旋回 #define turn_R0 OnRL(0,SPEED_CR);//右折 #define turn_R1 OnRL(-SPEED_CR,SPEED_CR);//右旋回 #define STEP 1 #define OTO PlaySound(SOUND_UP); //動作確認用の音 #define ARMOPEN RotateMotor(OUT_A,40,90); //アーム開 #define ARMCLOSE RotateMotor(OUT_A,-40,90);//アーム閉 #define KOUSATEN1 Off(OUT_BC);ARMCLOSE;RotateMotor(OUT_BC,40,100);OTO;//最初の交差点の動作 #define KOUSATEN2 Off(OUT_BC);RotateMotor(OUT_BC,40,100);OTO;//二番目の交差点での動作 #define SHOT OTO;OnFwd(OUT_BC,80);Wait(2500);//シュート **メインタスク [#o6335382] task main(){ SetSensorLight(S3); //センサー起動 int white=0;//白検出回数のの変数定義 int white=0;//白検出回数の変数定義 while(white==0){ if(SENSOR_3<Lblack){ turn_R0;//線の内側まで来てしまったときちょっと右に } else if(SENSOR_3<Sblack){ go_ST;//境界近くの黒線にあるときそのまま真っ直ぐ } else if(SENSOR_3<Swhite){ turn_L1;//境界近くの白紙側にあるとき旋回して左に } else if(SENSOR_3<Lwhite){//明るい白を検出したら�,瞭虻遒離廛蹈哀薀爐魑�動 go_ST;//1.直進 Wait(100); RotateMotor(OUT_B,40,100);//2,直角に合わせ旋回して方向転換 RotateMotor(OUT_C,-40,100); white++;//3,変数の値を増やし次のプログラムが起動するようにする } Wait(STEP); } while(white==1){//交差点�気鯆眠瓩垢襪泙任瞭虻� if(SENSOR_3<Lblack){//交差点と判断し動作を開始 KOUSATEN1;//交差点�気鯆眠瓩垢詁虻� white++;//変数の値を増やし次のプログラムが起動するようにする } else if(SENSOR_3<Sblack){//線の内側近くなったとき右に旋回移動 turn_R1; } else if(SENSOR_3<Swhite){//外側よりの境界を進む go_ST; } else if(SENSOR_3<Lwhite){//外側に反れたとき左に移動 turn_L0; } Wait(STEP); } long t0=CurrentTick();//交差点�気鯆眠瓩靴討�らの時間を計測 while(white=2){ if(SENSOR_3<Lblack&&CurrentTick()-t0>11000){//�気鯆眠瓩�11秒経ち濃い黒を検出したら交差点�兇箸澆覆� KOUSATEN2;//交差点�兇魄榮� white++;//変数の値を増やし次のプログラムが起動するようにする } else if(SENSOR_3<Sblack){//white==1の時と同じ移動をする turn_R1; } else if(SENSOR_3<Swhite){//white==1の時と同じ移動をする go_ST; } else if(SENSOR_3<Lwhite){//white==1の時と同じ移動をする turn_L0; } Wait(STEP); } long t1=CurrentTick();//交差点�兇鯆眠瓩靴討�らの時間を計測 while(white==3&&CurrentTick()-t1>10000){//10秒経つまで通常のライントレース if(SENSOR_3<Lblack){ turn_R1; } else if(SENSOR_3<Sblack){ turn_R0; } else if(SENSOR_3<Swhite){ go_ST; } else if(SENSOR_3<Lwhite){ turn_L0; } Wait(STEP); } SHOT;//シュート! } *感想 [#c0ba4d86] 前回とは逆に作成よりもプログラミングで非常に苦しんだ。 例で解決方法が色々示されていたもののそのままでは正確に動かず、最終的に全体を細かく区切って誤作動を少なく出来たものの長くなってしまったのが心残りだった、 しかし、新たなコマンドの方法を多く学べ、問題に対しても様々なアプローチが出来、他の班員と意見を交換し一緒に協力して取り組めたのはいい点だった。 その点は次回にも引き続き取り組んでいきたい。 &ref(./ライントレースアーム開け! (1).JPG,10%);