はじめに

LEGO MINDSTORMS EV3でライントレースを強化学習します。

まずは、EV3でPythonを動かせるようにします。

準備

numpyをEV3にインストールします。

まず、pip3をインストールします。

robot@ev3dev:~$ sudo apt-get update
robot@ev3dev:~$ sudo apt-get install python3-numpy

どちらも、かなり時間がかかります。

次に、pip3でnumpyをインストールします。

#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# ev3lt.py
#
# Copyright 2017-2018 Tohgoroh Matsui All Rights Reserved.
#
import ev3dev.ev3 as ev3
import environment as env
import numpy as np
import time


class EV3LineTrace(env.Environment):
    """EV3でライントレース問題。状態は (左光センサー観測値, 右光センサー観測値) で表される。"""

    states = 4 # 状態数
    actions = 2 # 行動数
    motor_l = ev3.LargeMotor('outB')    # 左モーター
    motor_r = ev3.LargeMotor('outC')    # 右モーター
    sensor_l = ev3.LightSensor('in2')   # 左光センサー
    sensor_r = ev3.LightSensor('in3')   # 右光センター
    sleep = 0.1 # スリープ時間

    @classmethod
    def init_state(cls):
        """初期状態として現在の状態を返す。"""
        state = cls.get_state()
        return state

    @classmethod
    def is_terminal(cls, state):
        """渡された状態が終端状態ならTrue, そうでないならFalseを返す。"""
        return False

    @classmethod
    def get_state(cls):
        """現在の状態(センサーの値)を返す。"""
        light_l = cls.sensor_l.reflected_light_intensity  # 左側光センサーの反射光の強さ
        light_r = cls.sensor_r.reflected_light_intensity  # 右側光センサーの反射光の強さ
        return (light_l, light_r)

    @classmethod
    def get_s(cls, state):
        """状態を状態番号に変換して返す。"""
        light_l, light_r = state[0], state[1]
        if light_l < 40 and light_r < 40:
            s = 0
        elif light_l < 40:
            s = 1
        elif light_r < 40:
            s = 2
        else:
            s = 3
        return s

    @classmethod
    def get_a(cls, action):
        """行動を行動番号に変して返す。"""
        return action

    @classmethod
    def get_reward(cls, state):
        """報酬を返す。"""
        light_l, light_r = state[0], state[1]
        if light_l < 40 or light_r < 40:  # どちらかの光センサーの値が40未満(黒)なら
            reward = 1.0
        else:
            reward = -0.01
        return reward

    @classmethod
    def take_action(cls, state, action):
        """行動を実行して状態を更新し、報酬と次の状態を返す。"""
        if action == 0:
            state_ = cls.turn_l()
        else:
            state_ = cls.turn_r()
        reward = cls.get_reward(state_)
        return reward, state_,

    @classmethod
    def str_state(cls, state):
        """状態を表す文字列を返す。"""
        light_l, light_r = state[0], state[1]
        return '(%.3f, %.3f)' % (light_l, light_r)

    @classmethod
    def str_action(cls, action):
        """行動を表す文字列を返す。"""
        if action == 0:
            str = 'turnL'
        else:
            str = 'turnR'
        return str

    @classmethod
    def turn_l(cls):
        """左に曲がる。"""
        cls.motor_l.run_forever(speed_sp=-25)   # 左のモーターを後ろに、
        cls.motor_r.run_forever(speed_sp=100)    # 右のモーターを前に回す
        time.sleep(cls.sleep)
        state_ = cls.get_state()
        return state_

    @classmethod
    def turn_r(cls):
        """右に曲がる。"""
        cls.motor_l.run_forever(speed_sp=100)    # 左のモーターを前に、
        cls.motor_r.run_forever(speed_sp=-25)   # 右のモーターを後ろに回す
        time.sleep(cls.sleep)
        state_ = cls.get_state()
        return state_

    @classmethod
    def stop(cls):
        """止まる。"""
        cls.motor_l.stop()
        cls.motor_r.stop()

    def __init__(self):
        super().__init__()
トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS