mBotは初期プログラムで、障害物回避動作とライントレース動作をさせることができます。今回は、それらを流用することで、ライン追従しながら障害物を検知して停止するプログラムを作成しました。
この記事では、Arduino(C言語ベース)を使った具体的なプログラムとそのポイントをご紹介します!

ライントレース用の黒色ラインの作成には、反射の少ない黒色マスキングテープがお勧めです。
(黒色マジックペンでは、反射してセンサーが黒色を認識しないことがあります)
「障害物回避×ライントレース」プログラム概要
作成するプログラムでは、以下の動作を実現します。
- ライントレースセンサーを用いて、ライン追従動作をさせる
- 超音波センサーを用いて、障害物を検知した際にmBotを停止させる
「障害物回避×ライントレース」プログラムの流れ
mBotのサンプルプログラム「mbot_factory_firmware」には、障害物回避とライントレースのプログラムが用意されています。今回は、そのプログラムを流用して作成することとします。
サンプルプログラムの内容把握
障害物回避プログラムの内容
「mbot_factory_firmware」の関数modeB()が障害物回避の関数です。内容は以下。
void modeB()
{
  uint8_t d = ultr.distanceCm(70);
  static long time = millis();
  randomSeed(analogRead(6));
  uint8_t randNumber = random(2);
  if((d > high) || (d == 0))
  {
    Forward();
  }
  else if((d > low) && (d < high)) 
  {
    switch (randNumber)
    {
      case 0:
        TurnLeft();
        delay(300);
        break;
      case 1:
        TurnRight();
        delay(300);
        break;
    }
  }
  else
  {
    switch (randNumber)
    {
      case 0:
        TurnLeft();
        delay(800);
        break;
      case 1:
        TurnRight();
        delay(800);
        break;
    }
  }
  delay(100);
}これをフローチャートにおこすと次のようになります。

超音波センサーで検出した障害物との距離が15cmより大きければ前進、15cm以下になれば方向転換をするプログラムとなっています。
ライントレースプログラムの内容
同様にライントレースのプログラムも見ていきます。関数modeC()が該当処理となります。
void modeC()
{
  uint8_t val;
  val = line.readSensors();
  if(moveSpeed > 230)
  {
    moveSpeed=230;
  }
  switch(val)
  {
    case S1_IN_S2_IN:/* ライン上 */
      Forward();
      LineFollowFlag = 10;
      break;
    case S1_IN_S2_OUT:/* 右に外れている */
       Forward();
      if (LineFollowFlag > 1)
      {
        LineFollowFlag--;
      }
      break;
    case S1_OUT_S2_IN:/* 左に外れている */
      Forward();
      if (LineFollowFlag<20)
      {
        LineFollowFlag++;
      }
      break;
    case S1_OUT_S2_OUT:/* 両方外れている */
      if(LineFollowFlag == 10) 
      {
        Backward();
      }
      if(LineFollowFlag < 10)
      {
        TurnLeft2();
      }
      if(LineFollowFlag > 10)
      {
        TurnRight2();
      }
      break;
  }
}こちらもフローチャートにおこしてみます。

ライントレースセンサー2つの検出結果をみて、前進するか方向転換するかを決めています。ライン上、もしくは片側だけ外れた時は前進。センサー両側ともラインを外れた際に、直前までの動作を確認して転換する方向を決めています。
「障害物回避×ライントレース」プログラムの設計
以上のサンプルプログラムを流用した場合、以下のフローが考えられます。

超音波センサーの検出距離が、ある一定距離より大きい場合は、ライントレースの処理(modeC)を実行させ、検出距離が小さい場合はmBotを停止させます。
「障害物回避×ライントレース」プログラム例
上で示したフローチャートをコードに書き起こすと次のようになります。loop()関数からコールするモードDのメイン処理です。
uint8_t high2 = 15;
void modeD()
{
  uint8_t d = ultr.distanceCm(70);
  uint8_t val;
  val = line.readSensors();
  if(moveSpeed > 230)
  {
    moveSpeed=230;
  }
  if((d > high2) || (d == 0))
  {
    switch(val)
    {
      case S1_IN_S2_IN:/* ライン上 */
        Forward();
        LineFollowFlag = 10;
        break;
      case S1_IN_S2_OUT:/* 右に外れている */
        Forward();
        if (LineFollowFlag > 1)
        {
          LineFollowFlag--;
        }
        break;
      case S1_OUT_S2_IN:/* 左に外れている */
        Forward();
        if (LineFollowFlag<20)
        {
          LineFollowFlag++;
        }
        break;
      case S1_OUT_S2_OUT:/* 両方外れている */
        if(LineFollowFlag == 10) 
        {
          Backward();
        }
        if(LineFollowFlag < 10)
        {
          TurnLeft2();
        }
        if(LineFollowFlag > 10)
        {
          TurnRight2();
        }
        break;
    }
  }
  else
  {
    RunStop();
  }
}void RunStop()
{
  MotorL.run(0);
  MotorR.run(0);
}「障害物回避×ライントレース」実行結果
このプログラムを実行した結果です。
ライントレースをしながら、障害物を検知して停止していることが分かります。また、障害物を取り除くと、前進を再開します。
まとめ
今回は、「障害物回避 × ライントレース」のプログラム例をご紹介しました。
このように、既存のサンプルプログラムを流用するだけでも、mBotの動作の幅を広げる面白いプログラミングが可能です。この記事を参考に、ぜひ自分だけのカスタマイズプログラムにも挑戦してみてください!
次回の記事では、さらに応用した動作のプログラミングをご紹介する予定ですので、お楽しみに!

 
  
  
  
   
					 
					 
					
 
					
