*プログラムの再修正 [#k7f8e282] もっと効率よく進むことができるようプログラムを修正します。 **赤外線反射センサの値を再確認 [#m6e92027] [[赤外線反射センサの値を確認>FDIIICHAPTER9.2#k8495ea4]]で作成したIRSensor.cを再度実行し、黒い地面から白い地面に移動する際のセンサの値を確認します。~ センサの値は、地面が白くなると急激に変化する訳でなく、徐々に変化しているのが分かります。~ #ref(line7.png) これにより、黒と白の中間点では全力で直進、黒の方へ少しずれたら少し右へ、白の方へ大きくずれたら大きく左へと走行することが可能ではないでしょうか。 **グラフを作る [#g558d264] 赤外線反射センサの値と左右の車輪の動きをグラフにしてみます。 白と黒の地面の中心を70としていますので、ここを中心に左右が最大出力になるようにします。 #ref(line8.png) グラフの横軸は赤外線反射センサの値、縦軸は車輪のスピードです。 赤いラインが右車輪、青いラインが左車輪です。 黒と白の真ん中(センサ値70)の時、両車輪とも最大速度1000となります(最大値は1023ですが簡略化のため1000としました)。 センサ値が70より小さい時は黒い方へずれているということなので、右車輪のスピードを下げて右へ曲がります。センサ値が小さくなるに従ってスピードを下げ右に曲がる量を増やします。 同様にセンサ値が70より大きい時は白い方へずれているということなので、左車輪のスピードを下げて左へ曲がります。センサ値が大きくなるに従ってスピードを下げ、左に曲がる量を増やします。 **計算します [#wd05ab8a] グラフを式にしてみます。~ ***右車輪 [#m1d1d081] 右車輪のスピードが最小値(0)から最大値(1000)へ変化する部分を考えます。~ スピードをY、センサ値をXとした場合、 Y = aX + b となります。これはXが70であればYは1000となるので、 1000 = 70a + b と置き換えます。これを最初の式に当てはめると Y = aX + 1000 - 70a となります。 ここでのaはグラフの傾きです。 aを大きくすると、センサ値に合わせて右車輪のスピードが大きく下がるため、急激な右旋回となります。aを小さくすれば、スピードは余り下がらなくなるため、ゆっくりとした右旋回となります。 aをどのような値にすれば良いかは、実際にライントレースをしながら決めます。 センサ値が20の時、スピードが0になるよう、aの値を20とします。 Y = 20X - 400 ***左車輪 [#s2cab8e6] 次に左車輪ですが、右車輪と異なりスピードが最大値(1000)から最小値(0)へ変化する部分を考えます。基本的に傾き以外右車輪と同じになります。但し、センサ値が120の時、スピードが0になりますので、aの値は-20となります。 Y = -20X + 2400 これでひとまずの計算は終了です。 **スピードを設定する [#v3af612b] グラフはセンサ値が70を境に反転していますので、70で処理を分割します。 #html{{ <pre class="brush:c"> DX_ReadByteData (100, 28, &GroundData, 10, NULL); if (GroundData < 70) { Direction (1000, GroundData * 20 - 400); } else { Direction (GroundData * -20 +2400, 1000); } </pre> }} 計算式をそのまま当てはめていますが、センサ値によってマイナスのスピードが作成されてしまいます。ロボット相撲と異なり、ライントレースはその場で旋回することはありませんので、スピードの最小値は0にする必要があります。 #html{{ <pre class="brush:c"> DX_ReadByteData (100, 28, &GroundData, 10, NULL); if (GroundData < 70) { if ((GroundData * 20 - 400) < 0) Direction (1000, 0); else Direction (1000, GroundData * 20 - 400); } else { if ((GroundData * -20 +2400) < 0) Direction (0, 1000); else Direction (GroundData * -20 +2400, 1000); } </pre> }} **プログラム完成 [#y8b96e69] #html{{ <pre class="brush:c"> #include <fd.h> // アクチュエータ操作 void Direction (short left, short right) { fd_DXSetSpeed (1, -right); fd_DXSetSpeed (2, left); } // メイン関数 void main (void) { uint8_t GroundData; fd_SetBeepCondition (FD_BEEP_MMI | FD_BEEP_PACKETERR | FD_BEEP_LOWVOLTAGE | FD_BEEP_BOOTUP); fd_SetUVThreshold (7.4); DX_ChangeBaudrate (1000000); fd_DXSetEndlessTurn (1, true); fd_DXSetEndlessTurn (2, true); while (!fd_GetPB () && !fd_rx_buff ()) { DX_ReadByteData (100, 28, &GroundData, 10, NULL); fd_printf ("ground: %3d\r", GroundData); if (GroundData < 70) { // 黒検知 if ((GroundData * 20 - 400) < 0) Direction (1000, 0); else Direction (1000, GroundData * 20 - 400); } else { if ((GroundData * -20 +2400) < 0) Direction (0, 1000); else Direction (GroundData * -20 +2400, 1000); } fd_Wait (10); } Direction (0, 0); // 停止 } </pre> }} 完成したプログラムを実行してみましょう。 前章のプログラムと比べ、上手にライントレースができているでしょうか。 中心となるセンサ値やグラフの傾きを変えながら、適合する値を調整してみましょう。 [[次のチャプターへ>FDIIICHAPTER9.4]] [[FDIII-HC Starter Kit Guide>LEARNINGGUIDE]]に戻る
(This host) = http://www.besttechnology.co.jp