ライン上にいるときは前進するようにプログラムしてみました。
左右に振りながら動くプログラムよりはっきりと速いのがわかります。 

精度もよく、ヘアピンカーブもOKです。センサーの数は1個です。
 /*  黒い線をトレースするロボット のプログラム  */
 //    作成者:山崎
 //    作成日:2005-11-18
 
 //右折のサブルーチン
 sub right()
 {OnRev(OUT_C);
  OnFwd(OUT_A);}
 
 //左折のサブルーチン
 sub left()
 {OnRev(OUT_A);
  OnFwd(OUT_C);}
 
 task main ()
 {
    SetSensor(SENSOR_2, SENSOR_LIGHT);//光センサーをセンサー2にひとつだけ付けました
 
    while (true ) {
                    OnRev(OUT_A+OUT_C);//前進
                    
                    if (SENSOR_2 > 40){ //ラインから外れたら
                                        
                                        ClearTimer(0);//右折時間を計るタイマースタート
                                        
                                        right();//右折
                                        until((SENSOR_2 < 40) || ((Timer(0)>2) && (SENSOR_2 > 40)));
                                        //センサーがラインに戻る または 0.2秒してもラインに戻らないと右折終了
                                        
                                        if ((Timer(0)>2) && (SENSOR_2 > 40)){  //0.2秒してもラインに戻らないときは
                                                                              left();//左折
                                                                              until(SENSOR_2 < 40);//ラインに戻るまで
                                                                            }
                                      } 
                          
                  } 
 }
*&size(25){わかったこと}; [#p1ae528f]
-光センサーは、白いところではセンサー>40、黒いところではセンサー<40。
-複雑な条件式でも()でくくってやればできる。
-untilはWaitより大事かもしれない。
-二つの処理のうちどちらかを選ぶ(今回は右折と左折)場合、どちらかをさせて、間違っていたらもう一方の処理に変える方法がある。
**Timerを使うと処理時間が計れる。これを利用すればそろそろ終了しているはずの処理が未完了のとき、その処理が間違った処理であったと判断できる。 [#u11a8be4]

これはこれからもよくでてきそうなのでテンプレート感覚で使えるようにまとめてみました。
 AまたはBの処理をしてやらないといけないとき
 { 
   ClearTimer(0);//Aの行動時間を計るタイマースタート
   A();
   until((処理効果が出たときの条件式) || ((Timer(0)>効果が出るまでの予想タイム) && (効果なしのときの条件式)));
   //効果がでる または 予想タイムになっても効果なしならAを終了
                                       
   if ((Timer(0)>効果が出るまでの予想タイム) && (効果なしのときの条件式))
   {
      //場合によってはここにAの処理でしてしまった間違った動作を訂正する文を挿入する
      B();
      until(処理効果が出たときの条件式);//効果が出るまで
                                       }
   }
*明るさを測るプログラム [#q182f8f5]
このプログラムは光センサーをセンサー1に付ければ本体には特別な改造なく使えるので、気になった人は是非1度お試し下さい。
いろいろな物の表面で試すと楽しいです。え!?そんなの使わなくてもViewを押せば見れるって?そんなつれないこと言わないでください(汗)

使い方
-Runを押すと、その場の光センサーの値を音で表します。
-低い音の鳴った回数が10の位の数、短い音の鳴った回数が1の位の数です。最初に10の位から鳴ります。
 //  明るさを測るプログラム 
 //    作成者:山崎
 //    作成日:2005-11-27
 //    変更日:2005-11-28
 //    変更点:%を使って簡単に書き換えました。
  
  task main ()
 {
  SetSensor (SENSOR_1, SENSOR_LIGHT);
  repeat ((SENSOR_1-SENSOR_1%10)/10) //10の位の数だけ低い音を鳴らします。
  {
    PlaySound (SOUND_LOW_BEEP);
    Wait (150);
  }
  Wait (200); //10の位の数を鳴らし終わると少し待ちます。
 
  repeat (SENSOR_1%10) //1の位の数だけ短い音を鳴らします。
  {
    PlaySound (SOUND_CLICK);
    Wait (100);
  }
 }

*&size(25){わかったこと}; [#g4c3f7a1]
-白と黒の明るさの値がとてもよくわかりました。やはり40が白と黒の値の丁度間になるみたいです。

白い部分は50,49,48,47など

黒い部分は33,31,30,27など

青い部分は27、黄色い部分は44、蛍光灯の真下は77、真っ暗な部屋(空中)では15、鏡の上は61でした。
-真っ暗な部屋でも物にセンサーを近づけると普通の値、白47や黒30になりました。
-真っ暗な部屋でも物にセンサーを近づけると普通の値、白47や黒30になりました。よって部屋の明るさは線の読み取りには関係ないとわかりました。
-茶色は40前後の値が出るので、これが白と黒の中間の明るさみたいです。
*&size(25){疑問点}; [#qcfc550e]
-サブルーチンの中に別のサブルーチンがあるとエラーが出るみたいだが、サブルーチンから別のサブルーチンは呼び出せないのか?(解決済)
-割り算の余りを返す命令などはないのか?(解決済)
**アドバイスなどありましたらこちらへ [#z8a29125]
-残念ながら NQC の仕様で、サブルーチンから他のサブルーチンを呼び出すことはできません。 -- [[松本(教員)]] &new{2005-11-24 (木) 12:06:52};
-紙や線の濃さによって閾値を調整する必要がありますが、白と黒の部分の一般的な明るさはどんな値になっているでしょうか? -- [[松本(教員)]] &new{2005-11-26 (土) 09:18:30};
-白と黒の部分の明るさの値を調べて載せました。 -- [[山崎]] &new{2005-11-28 (月) 01:57:29};
-割算の余りは『%』という演算子で得られます。(例) z = x % y -- [[松本(教員)]] &new{2005-11-28 (月) 18:01:31};
-早速書き換えてみました。 -- [[山崎]] &new{2005-11-28 (月) 19:18:17};

#comment

[[戻る>2005/C6/y0]]

[[C6のTOPへ>2005/C6]]
RIGHT:
tya&counter(today);
&counter(yesterday);
&counter(all);
//11月18より



トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS