#author("2020-02-14T20:38:47+09:00","shabuhara","shabuhara")
#author("2020-02-14T21:57:09+09:00","shabuhara","shabuhara")
[[2019b/Member]]
*目次 [#g9ed8aae]
#contents
*概要 [#k1f2be98]
課題2にて作成した~
黒いラインをトレースして球をつかまえるロボットです。~
*ロボットの説明 [#i3b792c1]
#ref(20200108155958.jpg)
今回はラインを追っかけて玉をキャッチすることが主な目的だったのでロボット自体は~
あまり特徴らしきものはありません。強いて言えば、かっこいいアームです。~
基本の走るタイプにアームと超音波センサー、光センサーがついています。~
このアームが重心がずれるにもかかわらず横についている理由は当初のボタンが押せなくなる~
致命的なミス解消と、横についているほうがかっこいいからこうなりました。~
やはり実際走らせていると左右に振る動作が多いので振り幅が大きくなっていた気がします。~
超音波センサーのついている位置はつけられる場所がなく不安いっぱいだったのですが、~
案外ちゃんと測定することが出来ていました。~
超音波センサーと対になっている感じでおしゃれなので問題は無いということになりました。~
#ref(20200108160222.jpg)
後は光センサーの高さが一番苦労したところでした。近すぎると見分けにくくなったり~
少しの段差で値が変わってしまう。遠すぎると周りの明るさに影響されやすくなる(気がする)。~
中程に置くことで環境による誤差もほとんど無くすことができました。~
#ref(20200108160252.jpg)
やたら画像でかいですね。画素数は落としたはずなんですけど。~
キャッチャーの籠は左右に揺れる玉を逃さないためになんかゴツゴツしてます。~
しかし割と軽量。~




*プログラムの紹介 [#y3e45929]
 
 #define Black 40  //しきい値
 #define White 65
 #define S 40
 #define LS 30
 #define TL OnFwd(OUT_B,S);Off(OUT_C); //左
 #define TR OnFwd(OUT_C,S);Off(OUT_B); //右
 #define GF OnFwd(OUT_BC,S); //前
 #define STEP 1
 #define by_crosstime 2000  //交差点前のところまでの時間
define郡ですが特に変わったものもなくトレースの型に交差点の手前までの定義を加えただけです。~
 
 
 void oikake(long tmin = j){
   long t0 = CurrentTick();
    while(CurrentTick()- t0 < tmin){  //三色見分け追いかけ
     if(SENSOR_1 < Black){TL;
 }else if(SENSOR_1 < White){
   GF;
 }else{
   TR;
 }
   Wait(STEP);
 }
 }
tmin秒の間、三色でラインをトレースするプログラム
 
 int L,K,b,f,h,g =0;
 sub follow_line(){      //黒線の回数を判定するところ 
   K = 0;             
   RotateMotorEx(OUT_BC,60,360,100,true,false); //横を向いて黒い線を数えるための準備をする
    Off(OUT_BC);//小休止
    Wait(100);
   for(int K = 0;K <= 6;K++){ //180°を6回に分けて判定してくれる   
    long t1 = CurrentTick();
    RotateMotorEx(OUT_BC,40,60,-100,true,false);
     Off(OUT_BC);
     Wait(10);
60度を6回行うことで360(180)度サーチする。判定の回数は6回になっておるので同じ線では反応しない。
      if(K>=0 && CurrentTick() - t1 >= 10){  //一応回転が早すぎたとき対策の時間指定
       if(SENSOR_1 <= Black){  
   L++;//黒線の本数を記録するカウンタ
 }  
    if(L > 3){  
   break;
   Off(OUT_BC);
 }  
 }  
 }   
 }   

 
 sub seigyo_1(){  //最初に交差点に行くまでの進み方
   if(L<=2){    //黒線を3回見つけたときはちょっと前に進む
   oikake(STEP);
 }
   else if( L ==3){
     RotateMotorEx(OUT_BC,60,180,100,true,false);
     Off(OUT_BC);
     Wait(500);
     OnFwd(OUT_BC,S);
     Wait(200);
     b++;    //交差点を見つけた回数で行動を決めるためのカウンター
 }
 }
最初に交差点を見つけるまでの関数。黒線の数が2本までならトレースを続行し、3本なら~
交差点に引っかからないように少し進んでから交差点の回数のカウンターを更新~

 
 sub seigyo_2(int f = v){  //2回目の交差点用のやつ
   if(L<=2){ 
   oikake(STEP);
 }
   else if( L ==3){
    RotateMotorEx(OUT_BC,60,-180,100,true,true);
    OnFwd(OUT_BC,S);
    Wait(200);
    RotateMotorEx(OUT_BC,60,180,100,true,true);
    OnFwd(OUT_BC,S);
    Wait(f);
    b++;
 }
 }
二回目に交差点を見つけるまでの関数。交差点を発見するとボールのあるラインまで時間指定で移動させる。~
時間指定では電池次第であまりうまく行かないため角度指定で行うべきだったなと思っている~

 
 sub seigyo_3(){  //ボールキャッチするやつ
   for(h = 0;h<3000;h++){ //千回くらい判定アンド進みをする
    OnFwd(OUT_BC,LS);
    Wait(g);
    g++;
   if(SENSOR_4 <= 11){ //見っけて捜索をストップ
 break;
 }
 }
   if(SENSOR_4 <= 11){
    RotateMotor(OUT_A,LS,135); // キャッチ
 }
 }
forループで直線上に見つけるまで3000回探すところ。~
このような力技ができるところがコンピューターのすごい(面白い)ところだと思う。

 
 task main(){
   SetSensorLight(S1);
   SetSensorLowspeed(S4);
   GF;
   Wait(200);
   oikake(by_crosstime); //速さのために交差点付近までは速いトレース
    while(b==0){    //bの値は関数seigyo内で更新される
    while(b==0){    //bの値は関数seigyo1内で更新される
   follow_line();
   seigyo_1();
 }
   oikake(1000);
   while(b==2 && b==1){ //b内で2回更新されるタイミングがあり、同じプログラムで行けるため
    follow_line();
   while(b==2 && b==1){ //bはで2回更新されるタイミングがあり、同じ関数で行けるため~
    follow_line();      //1と2を兼用している
    seigyo_2(200);
 }
   if(b == 3){
    seigyo_3();
    RotateMotorEx(OUT_BC,-60,360,100,true,false);
    seigyo_3();     //b=3でキャッチする関数を起動
    RotateMotorEx(OUT_BC,-60,360,100,true,false); //; キャッチが終わったら反転
    oikake(3000);
 }else{
    Off(OUT_BC);
    Off(OUT_BC); //ボールが見つからなかった場合一旦止まって反転して帰る
    RotateMotorEx(OUT_BC,-60,360,100,true,false);
    b++;        
 }
   while(b<4){
    follow_line();
   while(b>=4){
    follow_line(); //帰りの道は真っ直ぐ行くので普通のトレースをさせる
    seigyo_1();
   
 }
 }



*プログラムの反省 [#v41feefa]
今回のプログラムでは、センサーを左右に振って黒線に反応した数を覚えて~
次の行動を決めるというやり方を採っています。これは課題2に入った際に、一つのセンサー~
を用いて交差点やT字路を見分けると説明された際に真っ先に思いついたやり方でした。~
5色見分けるやり方が授業では紹介されていたのでそちらにしようかとも思いましたが、~
前にもこのやり方を試した先輩がいるとのことだったので思い切りこれを採用しました。~
黒い線を探す関数とその後に行動する関数が分けてありますがこれは交差点を通過した数を~
覚えて通った回数によって動作を変えるためです。~
黒線の回数を判定するところのプログラムはこの中では一番のお気に入りです。~
そのforループの中の黒線の数を数えるLの変数の条件の時間は、一本で複数検出しないための保険です。~
電池交換をしたら急にハッスルして速さが意味わかんなくなった為つけた保険でした。~
forループで分割して判定できる回数を増やすのは汎用性が高くていいと思います。~
前回よりは慣れたとはいえ、まだまだ上手く~
まとめられていない部分や、仕様が理解できていない~部分があるので課題3ではより頑張りたいと思います。~

*反省 [#jc75cde5]
ここまでさんざやったことを書いてきましたが、発表会の前日に改良案を思いつき~
プログラムを作ったのですがライントレースがうまく行かなくなりその場で回りだす~ようになってしまいました、前に戻そうとするも~
バックアップは5行書いたままのもので復活はできませんでした。~
ほとんど流れは変わっていないので僅かな違いですが、完成品にはなりませんでした。~
なので上のプログラムは変更後のもので横のコメントも一部コンセプトとなっています。~
トライ・アンド・エラーで変更しての繰り返しだったのでバックアップを更新する~
癖がつかなかったのかなと思っています。~
課題3では今回の教訓を生かして保存をこまめにに取っていくようにしようと思っています。~

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