黒い線をたどって走る「ライントレースロボット」の作り方と制御理論

「床に描かれた黒い線を、ロボットがまるで磁石に吸い寄せられるように自動で追いかけて走っていく……」

ロボット開発を始めた人が、自律走行の面白さを最初に体感できる金字塔的なプロジェクト。それが「ライントレースロボット(ラインパトロールカー)」です。

ライントレースは単なる「おもちゃの工作」ではありません。工場の敷地内で部品を自動搬送する無人搬送車(AGV)や、ロボコン(WROやロボカップジュニアなど)の競技課題としても広く活用されている本格的な自動運転技術の基礎です。

この記事では、ライントレースロボットの基本的な仕組みから必要なパーツ、そしてカクカクしたぎこちない走りからプロ並みの滑らかな走りへ劇的に進化させる「制御理論(オンオフ制御からPID制御まで)」を徹底解説します!

1. ライントレースロボットってどんな仕組み?

ライントレースロボットは、「床(白)とライン(黒)の反射率の違い」をセンサーで読み取り、その情報をもとに左右のモーターの速度を調整して線の上を走り続けます。

【全体システムのながれ】
  1. 下向きに取り付けた赤外線センサーが床の「白/黒」を検知(入力)
  2. マイコンが「右にズレた」「左にズレた」と判定(制御)
  3. 左右のモーターのスピードに差をつけて、車体の向きを補正(出力)

人間で例えると、「白線からはみ出さないように下を見ながら、右足と左足の歩幅を微調整して歩く」ような作業を、1秒間に何十回・何百回というハイスピードで繰り返しているのです。

2. 必要なパーツと組み立て構成

まずは、ライントレースロボットを作るために必要なハードウェア(メカ・電子パーツ)を整理しましょう。

パーツ名 役割・選定のポイント 数量
ロボットシャーシ(2輪+キャスター) 左右独立して回る2つの駆動輪と、方向転換を邪魔しない自在キャスター(1個) 1セット
ギヤ付きDCモーター 左右のタイヤを回転させる動力源 2個
マイコンボード(Arduino Unoなど) センサー値を読み取り、モーターへ指示を出す「脳」 1個
モータードライバーモジュール 左右のモーターの速度(PWM)と回転方向をコントロールする 1個
ラインセンサーモジュール(赤外線フォトリフレクタ) 床に向かって光を出し、白と黒を識別するセンサー 2個〜5個
電源(電池ボックス / LiPoなど) マイコンおよびモーターに電気を供給する 1セット

3. センサーの基本原理:赤外線で「白」と「黒」を見分ける

ラインセンサー(フォトリフレクタ)の内部には、「赤外線LED(発光部)」と「フォトトランジスタ(受光部)」が隣り合わせで入っています。

【白地(床)の場合】                      【黒線(ライン)の場合】
   [発光部] ──► 赤外線 ──┐                  [発光部] ──► 赤外線 ──┐
                         │ (反射)                                 │ (吸収される)
   [受光部] ◄── 光を感知 ┘                  [受光部] ◄── 光が戻らない!
   ⇒ 電圧:LOW (または高数値)                 ⇒ 電圧:HIGH (または低数値)

  • 白地の上: 発射された赤外線が白地で跳ね返り、受光部に届くため「白」と認識。

  • 黒線の上: 黒い色は光を吸収するため、跳ね返ってくる赤外線が極めて少なくなり「黒」と認識。

マイコンは、この「白/黒」のセンサー信号をリアルタイムにチェックして、自分がラインの真ん中にいるかどうかを判断しています。

4. 段階別・ライントレースの「制御アルゴリズム」

ここからが本題です!ロボットを線に沿って走らせるための「プログラムの組み立て方(アルゴリズム)」には、難易度と走行性能に応じたレベルがあります。

Level 1:超基本!「オン・オフ制御(デジタル2値制御)」

センサーを左右に2個配置した、最もシンプルな制御方法です。

【2センサーの配置イメージ】
     (左センサー)  [  黒線  ]  (右センサー)
          │                      │
         白(反射あり)          白(反射あり)  ⇒ まっすぐ進む!

走行ロジック(4つのパターン)

  1. 左:白 / 右:白 ──► ラインの真ん中を走っている! 【両方のモーターを前進】

  2. 左:黒 / 右:白 ──► 車体が右にズレた(左が黒線に乗った)! 【右モーターのみ回転(左へ旋回)】

  3. 左:白 / 右:黒 ──► 車体が左にズレた(右が黒線に乗った)! 【左モーターのみ回転(右へ旋回)】

  4. 左:黒 / 右:黒 ──► ゴール線または交差点! 【停止】

⚠️ オン・オフ制御のメリットとデメリット

  • メリット: if 文(条件分岐)だけでプログラムが書けるため、超かんたん!

  • デメリット: 「完全に曲がる」か「まっすぐ行く」かの2択しかないため、カクカクと首を激しく振りながらジグザグ走行になってしまい、スピードが出せません。

Level 2:滑らかさを実現する「P制御(比例制御)」

カクカク走行を卒業し、車体をスムーズに滑らかに走らせるために登場するのが「P制御(Proportional Control:比例制御)」です。

ここでは、アナログ入力(0〜1023)が読み取れるラインセンサーや、3個以上の複数センサーアレイを使用します。

「ズレの大きさ」に応じて曲がり具合を変える!

P制御の考え方は非常にシンプルです。

「ラインの中心からの『ズレ(誤差:Error)』が小さいときは少しだけ補正し、ズレが大きいときだけ大きくハンドルを切る!」

【P制御の基本数式】
  補正量(Turn) = 誤差(Error) × Pゲイン(Kp)

  ・右モーターのスピード = 基本速度 - 補正量
  ・左モーターのスピード = 基本速度 + 補正量

  • Error(誤差): 「理想のライン中心位置」と「現在のロボットの位置」の差。

  • Kp(Pゲイン): 補正の強さを決める調整係数(パラメーター)。

P制御を導入すると、直線を走っているときはほぼ修正を加えずに高速で走り、ゆるやかなカーブでは滑らかに旋回し、急カーブだけ大きく曲がるという人間のような自然でスムーズな走りが可能になります!

Level 3:競技用・極限の走り「PID制御(ピー・アイ・ディー制御)」

ロボコンで全国大会を目指すような本格派マシンに搭載されるのが「PID制御」です。

PID制御は、先ほどの「P(比例)」に、「I(積分)」「D(微分)」の2つの要素を掛け合わせた最強の制御理論です。

【PID制御の構成要素】
  P (Proportional:比例) ⇒ 「今のズレ」に合わせて修正する(基本の力)
  I (Integral:積分)     ⇒ 「過去のズレの積み残し」を計算して、ジワジワかかる偏りを直す
  D (Derivative:微分)   ⇒ 「未来のズレの急変化(勢い)」を予測して、行き過ぎ(ハンチング)を抑えるブレーキをかける!

なぜ「D(微分)」が必要なの?

P制御だけだと、急カーブから抜けた直後に勢い余って反動で反対側に飛び出してしまう現象(オーバーシュート・ハンチング)が起きます。

そこに「D(微分制御)」を加えることで、「あ、今急激に車体が傾いたから、あらかじめ強めのブレーキをかけておこう!」という予測制御が働き、吸い付くような高速コーナーリングが可能になります!

5. ArduinoでのP制御サンプルプログラム

3つのセンサー(左・中・右)を使った、P制御ライントレースのコード例です。

C++

// ピン設定
const int SENSOR_LEFT   = A0;
const int SENSOR_CENTER = A1;
const int SENSOR_RIGHT  = A2;

const int MOTOR_LEFT_PWM  = 5;
const int MOTOR_RIGHT_PWM = 6;

// パラメータ調整
const int BASE_SPEED = 150; // 基本スピード (0~255)
const float KP = 0.5;       // Pゲイン(コースに合わせて調整)

void setup() {
  pinMode(MOTOR_LEFT_PWM, OUTPUT);
  pinMode(MOTOR_RIGHT_PWM, OUTPUT);
}

void loop() {
  // 1. 各センサーのアナログ値を読み取る(黒:数値が大きい / 白:数値が小さいと仮定)
  int valL = analogRead(SENSOR_LEFT);
  int valR = analogRead(SENSOR_RIGHT);

  // 2. 左右の差から「ズレ(Error)」を計算
  int error = valR - valL; // 右に寄るとプラス、左に寄るとマイナス

  // 3. P制御による補正量を算出
  int turn = error * KP;

  // 4. 左右のモーター速度を決定
  int leftSpeed  = BASE_SPEED + turn;
  int rightSpeed = BASE_SPEED - turn;

  // 5. 0〜255の範囲に収める(制限処理)
  leftSpeed  = constrain(leftSpeed, 0, 255);
  rightSpeed = constrain(rightSpeed, 0, 255);

  // 6. モーターに速度を出力
  analogWrite(MOTOR_LEFT_PWM, leftSpeed);
  analogWrite(MOTOR_RIGHT_PWM, rightSpeed);
}

6. 上達のためのチューニングテクニックとトラブル対策

プログラムを書いたら、実際のコースを走らせてパラメータを微調整(チューニング)していきます。

① 「しきい値(閾値)」のキャリブレーション

部屋の明るさやライトの当たり具合によって、「白」と「黒」のセンサー数値は毎日変わります。

走らせる前に、「白い場所の数値」と「黒い場所の数値」を読み取って中間値(しきい値)をプログラム上で自動計算させる「キャリブレーション処理」を入れておくと、どんな場所でも安定して走れるようになります。

② センサーの高さと傾きを調整する

センサーと床の距離は「3mm〜5mm程度」が最も感度が良くなります。遠すぎると光が拡散して白黒の区別がつかなくなり、近すぎると擦ってしまいます。

③ ゲイン(Kp)の調整手順

  1. まずKpを小さな値(0.1など)にする。

  2. 直線は走るがカーブで曲がりきれない場合、徐々にKpを大きくしていく。

  3. 大きくしすぎて直線で蛇行(ウネウネ)し始めたら、少し値を戻す。

7. まとめ:制御理論を学んでマシンを極限まで加速させよう!

今回のまとめです。

  1. ライントレースは赤外線センサーで床の反射光(白/黒)を読み取るのが基本!

  2. 最初は「オン・オフ制御(If文)」で確実に動く楽しさを知ろう!

  3. 滑らかに走らせたいなら「P制御(ズレに応じた補正)」を取り入れよう!

  4. 速さを追求するなら「PID制御」をマスターして、吸い付くようなコーナーリングを目指そう!

「自分の書いた数式やプログラムによって、ロボットの走りの質が劇的に変わる」

これこそが、ロボットプログラミングの最大の醍醐味であり快感です。

まずは2つのセンサーとシンプルなコードからスタートし、少しずつP制御やPID制御に挑戦して、コース最速のマシンを作り上げてみてください!