# マイクロマックイーン プラス (micro:Maqueen Plus) 自動運転(ライントラッキング)




# 10.1. 目標




黒い路線が書かれているマップの上で、マイクロマックイーン プラス (micro:Maqueen Plus)を自律的にライントラッキングしながら、運転させるためのプログラミング方法を学習します。


# 10.2. 必要な機材




# PC利用時に必要な機材

No. 名称 個数 HW/SW 用途 補足
01 micro:bit(v2)本体 1 HW マイクロマックイーン プラス (micro:Maqueen Plus)のコントロール用。
プログラミングはmicro:biに対して行う
02 micro:bit用 ケース 1 HW micro:bit保護 ※ 必須ではない
03 micro:bit用 USBケーブル 1 HW micro:bitとPCの接続 Type-AとType-C両方対応できると様々な端末で利用しやすい
04 マイクロマックイーン プラス (micro:Maqueen Plus) 1 HW 車体本体
05 単3型乾電池 4 HW マイクロマックイーン プラスとmicro:bitへの電源供給
06 Chromebook、MacOS、WindowsのPC 1 HW MakeCode操作用
07 Google Chrome 1 SW MakeCodeアクセス用
08 トラッキング用マップ 1 - ライントラッキングテスト用

# タブレット・スマートフォン利用時に必要な機材

No. 名称 個数 HW/SW 用途 補足
01 micro:bit(v2)本体 1 HW マイクロマックイーン プラスのコントロール用。
プログラミングはmicro:biに対して行う
02 micro:bit用 ケース 1 HW micro:bit保護 ※ 必須ではない
03 マイクロマックイーン プラス (micro:Maqueen Plus) 1 HW 車体本体
04 単3型乾電池 4 HW マイクロマックイーン プラスとmicro:bitへの電源供給
05 タブレット・スマートフォン 1 HW micro:bitアプリ操作用
06 micro:bit アプリ 1 SW micro:bitアプリ操作用
07 トラッキング用マップ 1 - ライントラッキングテスト用



# 10.3. MakeCodeブロックの概要




マイクロマックイーン プラス (micro:Maqueen Plus)の底部には、5つのグレースケールセンサーがあり、グレースケールセンサーは近距離で物体表面のグレースケールを検知することが可能です。
センサーに二つの球体があり、透明な球体から赤外線を発光し、黒い球体で物体で反射された赤外線を受光し、暗い色は光(赤外線を含む)を吸収するため、暗い色の場合反射される光の量が少なくなり、それによってグレースケールを検知します。

No. ブロック 概要 機能
01 iftiny-Micro-Maqueen-Plus-Tutorial-Line-Tracking-1201 ライントラッキング用ブロック ・ センサーの選択:車体底部の5つのグレースケールセンサー(L2, L1, M, R1, R2)
・ 黒線検出時の戻り値:1
・ 黒線非検出時の戻り値:0
01 iftiny-Micro-Maqueen-Plus-Tutorial-Line-Tracking-1202 グレースケールセンサー用ブロック ・ センサーの選択:車体底部の5つのグレースケールセンサー(L2, L1, M, R1, R2)
・ 戻り値:検出されたグレースケール値



# 10.4. 動作イメージ




黒い路線に沿って、マイクロマクイーン (micro:Maqueen)が自動運転します。

参考情報


  • マップを自作することも可能です。黒いテープなどである程度太い線を作ることが必要です。



# 10.5. プログラミング例 1




車体を円形の黒線マップに配置すると、車体は底部に設定された 3つのグレースケールセンサーを使用して、車体が黒線上を走行しているかどうかを検出します。黒線から外れた場合、進行方向を修正し、黒線に戻ります。
マイクロマックイーン プラス V2(micro:Maqueen Plus V2)には5つのグレースケールセンサーがあります。このプログラムでは、3つのセンサー、L1、M、R1を使用して黒い線を検出します。L2とR2はまだ使用されていません。




# MakeCodeプログラミング例(ブロック)





# MakeCodeプログラミング例(JavaScript)

function line_tracking() {
    if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 0) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eAllMotor, MyEnumDir.eForward, 100)
    } else if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 0) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 40)
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 100)
    } else if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 0) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 0)
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 100)
    } else if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 1) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 100)
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 40)
    } else if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 1) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 100)
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 0)
    }
}

DFRobotMaqueenPlusV2.I2CInit()
basic.forever(function on_forever() {
    while (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 0 || DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 0 || DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 0) {
        line_tracking()
    }
})



# MakeCodeプログラミング例(python)

def line_tracking():
    if DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 0:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_ALL_MOTOR, MyEnumDir.E_FORWARD, 100)
    elif DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 0:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 40)
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 100)
    elif DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 0:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 0)
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 100)
    elif DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 1:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 100)
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 40)
    elif DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 1:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 100)
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 0)
DFRobotMaqueenPlusV2.i2c_init()

def on_forever():
    while DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 0 or DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 0 or DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 0:
        line_tracking()
basic.forever(on_forever)



# MakeCodeプログラミング例のQRコード

マイクロマックイーン プラス (micro:Maqueen Plus) 自動運転(ライントラッキング) プログラムサンプル QRコード




# 10.6. プログラミング例 2




上記のプログラミングの例では、両側で2つのセンサーL2とR2を使用してなく、誤って車体が大きく黒線から外れた場合、黒線を見つけて走り続けることが難しくなります。
次の例では、プログラミングを改良し、5つのセンサーを使用し、車体が間違った経路にあることを検知した時、ラインに戻ることができるようにします。



# MakeCodeプログラミング例(ブロック)





# MakeCodeプログラミング例(JavaScript)

function line_tracking () {
    if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 0) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eAllMotor, MyEnumDir.eForward, 100)
    } else if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 0) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 40)
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 100)
    } else if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 0) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 0)
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 100)
    } else if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 1) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 100)
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 40)
    } else if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 1) {
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 100)
        DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 0)
    }
}
DFRobotMaqueenPlusV2.I2CInit()
basic.forever(function () {
    while (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL2) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR2) == 0) {
        if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL2) == 1 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR2) == 0) {
            DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 0)
            DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 100)
            if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 1 || DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 1 || DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 1) {
                line_tracking()
            }
        } else if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL2) == 0 && DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR2) == 1) {
            DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eLeftMotor, MyEnumDir.eForward, 100)
            DFRobotMaqueenPlusV2.controlMotor(MyEnumMotor.eRightMotor, MyEnumDir.eForward, 10)
            if (DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eL1) == 1 || DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eM) == 1 || DFRobotMaqueenPlusV2.readLineSensorState(MyEnumLineSensor.eR1) == 1) {
                line_tracking()
            }
        }
        line_tracking()
    }
})



# MakeCodeプログラミング例(python)

def line_tracking():
    if DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 0:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_ALL_MOTOR, MyEnumDir.E_FORWARD, 100)
    elif DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 0:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 40)
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 100)
    elif DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 0:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 0)
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 100)
    elif DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 1:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 100)
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 40)
    elif DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 1:
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 100)
        DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 0)
DFRobotMaqueenPlusV2.i2c_init()

def on_forever():
    while DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L2) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R2) == 0:
        if DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L2) == 1 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R2) == 0:
            DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 0)
            DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 100)
            if DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 1 or DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 1 or DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 1:
                line_tracking()
        elif DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L2) == 0 and DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R2) == 1:
            DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_LEFT_MOTOR, MyEnumDir.E_FORWARD, 100)
            DFRobotMaqueenPlusV2.control_motor(MyEnumMotor.E_RIGHT_MOTOR, MyEnumDir.E_FORWARD, 10)
            if DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_L1) == 1 or DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_M) == 1 or DFRobotMaqueenPlusV2.read_line_sensor_state(MyEnumLineSensor.E_R1) == 1:
                line_tracking()
        line_tracking()
basic.forever(on_forever)



# MakeCodeプログラミング例のQRコード

マイクロマックイーン プラス (micro:Maqueen Plus) 自動運転(ライントラッキング) プログラムサンプル QRコード





Last Updated: 2/5/2023, 3:42:18 PM