25 Jul 2017, 13:23

MQTTでMindstorms EV3のロボットカーを パソコンのキーボードからリモコン操作

LEGO Mindstorms EV3 を パソコンのキーボードから操作してみます。

私は、LEGO Mindstorms EV3の教育版を買ったので、家庭版と違いリモコンがありません。でも、ラジコンのようにロボットカーを操作したい!そこで、MQTTというプロトコルを利用して、ノートPCのキーボードを使ってロボットカーを制御する方法を思いつきました。

まずは、結果をどうぞ!

[https://www.youtube.com/embed/kl_07BWGNWo?ecver=1]

環境

  • Publisher(PC) Ubuntu 16.04
  • Subscriber(ev3) ev3dev
  • Python 3.6
  • ev3dev-lang-python

ロボットの組み立て

この本に載っているtribotを作成しました。

Setup

MQTTという軽量な通信プロトコルを使った方法がev3devのサイトに紹介されていたので、それを参考にする。

MQTTではpublisher(出版者)が発するメッセージをbroker(仲介者)がsubscriber(購読者)へ配信する。今回は、publisherが ノートPC, brokerとsubscriberが ev3になる。

ev3に brokerサーバソフトをインストールする。mosquittoというソフトをインストール

sudo apt-get install mosquitto

インストールが完了すると、サービスが立ち上がる。

続いて、mqttをPythonで使うための pahoというソフトをノートPCと ev3の両方にインストール。

sudo apt-get install python3-pip
sudo pip3 install paho-mqtt

PC 側

pip3 install paho-mqtt

これで、MQTT で通信する準備は整った。

punput

Pythonで押されたキーボードのキーの取得をするために、punputというライブラリを利用する。

ラズパイカーで同じようなことを考えている人のブログ記事を発見した。これはありがたい。

コード

最後に、書いたコードが以下。これで、キーボードの十字キーを使ってロボットカーをリモコン代わりに操作することができた。

23 Jul 2017, 09:30

Afrel楕円コースの軌道をロボットカーでPID制御を使ってシミュレートしてみた

[mathjax]

はじめに

Udacityで Artificial Intelligence for Roboticsを受けている。

[blogcard url=”https://www.udacity.com/course/artificial-intelligence-for-robotics–cs373″]

この講座は、Googleカーの要素技術について学ぶ講座。 講師は、Udacityの創立者にしてGoogleカーの開発者、セバスチャン・スラン氏だ。

lesson5のテーマはPID制御。

この記事では、PID制御の概要を自分なりに整理し、目標とする軌道上をロボットが動くシミュレーション(Homework5.4)問題を書く。

PID制御とは

講義資料

講義動画

[https://www.youtube.com/embed/-8w0prceask]

PID制御とは、制御に使われる古典的な手法。P, I, D はそれぞれ、

  • P ・・・Propotional(比例)
  • I ・・・Integral(積分)
  • D ・・・Differential(微分)

を意味している。

今、自動車の制御を考える。目的とする基準軌道(横座標)と、車との距離をCross Track Error(CTE) という。

このときの望ましい制御は、CTEに比例して車のハンドルを切ること。そうすることで、スムーズに基準軌道へと車を近づけることができる。

今回、実験に使ったコードは以下。講義のなかのコードから抜粋した。

P 制御

Pは Propotional(比例)を表す。CTEに比例してハンドルを切る。式で表すと、

$$

steering = – \tau_p ・CTE

$$

厳密には、0 – \tau_p ・CTE としている。この問題設定では、xy座標で考えると、y=0を基準軌道としている。なので、(目標値) – (出力値) において、(目標値)が0となり、マイナス項だけが残る。

これをP制御という。P制御は、CTEが小さくなる、基準軌道に近づくに従って、修正量も比例して小さくなるようになっている。

しかし、P制御には、問題がある。以下の図のように、P制御しようとすると、基準軌道を通り越す(オーバーシュートという)してしまう。基準軌道に近づいては離れを繰り返して、安定しない。

PD制御

そこで、時間tで微分したCTEを式に加える。CTE_DIFFは時刻t-1におけるCTEから時刻tのCTEを引いた値。

$$

steering = – \tau_p ・CTE – \tau_d ・CTE_DIFF

$$

これによって、基準軌道にそった結果が得られた。

これを、PD制御という。

微分項を加えることで、制御の 反応性 が増す。この基準軌道の例では、仮に急激なCTEの減少が起こった場合、下の方にsteerを切りすぎないようにCTE_DIFFの値が大きくなって、オーバーシュートすることを防ぐ。

PID制御

I制御は、理解が曖昧で自分の言葉で説明できるかわからないので、参考にしたサイトの言葉を引用します。

偏差が小さいときに操作量が小さくなり過ぎてしまい、制御量が目標値とずれたところで安定してしまうということです。P制御の制御量は目標値より下側で安定してしまいます。この制御量と目的地の差を「定常偏差」あるいは「オフセット」と呼びます。

これは、例えば、タイヤが少し傾いていて、ハンドルを一定に切っても基準軌道に近づいてくれないようなシチュエーションで発生する。講義では、以下のようなメソッドで10度タイヤをずらすようなことをやっていた。

  robot.set_steering_drift(10.0/180.0*pi)

以下は、タイヤがずれた状態でのPD制御。

また引用。

ライントレーサの場合、P制御のパラメータ(Kp)が適正であれば、直線を走っているとき制御量は目標値付近で安定します。しかし、カーブがはじまるとオフセットが発生します。

カーブがはじまったとき、P制御によってその時点ごとの制御量に応じた操作量を決定し、カーブを曲がろうとします。目標値から離れれば離れるほど操作量が上がるP制御ですが、それは長所であると同時に短所にもなります。なぜなら、偏差が小さいと操作量も小さくなり、カーブの最中に偏差0の位置まで戻れず、カーブの外側に寄ってしまうからです。この状態が、目標値と違う場所で安定してしまう“オフセットが発生している状態”です。

オフセットが発生していてもカーブを抜けられればよいのですが、場合によってはコースアウトしてしまうことがあります。では、Kpを大きくし偏差が小さいときの操作量も大きくなるようにしてはどうでしょうか?

こうすることで、オフセットの発生は防げます。しかし、P制御では現在の値しか見ないため、いま直線にいるのか、カーブにいるのかが分かりません。そのため、P制御でせっかく力の抜き方を決めているのにもかかわらず、P制御のパラメータを大きくすると、カーブの間はいいのですが直線に戻っても操作量が大きくなってしまいます。その結果、せっかくオンオフ制御から改善したハンチングが再発する可能性があります。

そこで、「I制御」を用いてカーブにいる間だけ、操作量を上げるようにしましょう。

というわけで(笑)、I制御が必要となってきます。PD制御にIを加えた、最終的なPID制御式は、以下。

$$

steering = – \tau_p ・CTE – \tau_d ・CTE_DIFF – \tau_i ・* int_CTE

$$

$int_CTE$ は、時刻tまでのCTEの総和。これがハンチングに効いてくる。実験結果は以下。

Homework5.4

AI for Roboticsの Homework5.4は、レーストラックの軌道上をPID制御を使ってロボットカーを走らせるシミュレーションをすること。

自分は、課題のレーストラックを少し修正して、Afrelから売り出されている楕円コースの軌道をロボットが描くように修正してみた。

寸法は実物と同じなので、mindstorms ev3で実際にロボットカーをつくって走らせれば、軌道上をロボットが走行するはず!!実物を走らせるのは、次回!!

参考

28 Jun 2017, 13:38

LEGO Mindstorms教育版で作成可能なロボット

LEGO Mindstormsの教育版(#45544)を購入したので、ネットで手に入る設計図を調べた。

結論からいうと、以下のページにまとまっている。

標準セットで作成できるロボット

標準セット(45560)で作成できるロボットは以下の種類

  • Gyro Boy
  • Puppy
  • Color Sorter
  • Robot Arm
  • Robot Educator Model(たくさんあるので省略)

拡張セットで作成できるロボット

拡張セット(45560)で作成できるロボットは以下の種類

  • Elephant
  • Remote Control
  • Spinner Factory
  • Stair Climber
  • Tank Bot
  • Znap

拡張セットは、15000円くらい。

非公式

頑張ったらつくれた。

自分でつくるには・・・

自分で想像力をはためかせて作るには、以下の本が役に立ちそう。

まあ、そんな才能はないのだが。

レゴの設計図を見るたびに、よくこんなこと思いつくなと思う。

追記分

LEGO Design Builder(http://ldd.lego.com/ja-jp/) というソフトウェアがすごそう。

27 Jun 2017, 13:10

3000 回転んでも立ち上がれなかったロボット

前回、CartPole 問題が Q-Learning でやっと解けたので、 CartPole 問題を応用して、レゴマインドストームの GyroBoy で倒立振子を試みた。

結果

3000 回転んでも立ち上がらなかった。ヾ(´∀`)ノ

現実は、シミュレーション通りにはいかなかった。

しかし、悲観的になってはいけない。

始めは 1 秒しか立てなかったのが、5 秒立てるようになったのだ!!

ソースコード

gist にあげました。

25 Jun 2017, 13:47

LEGO Mindstorms で GyroBoy を組み立てた

LEGO MindStorms EV3 を買ったので、まずは GyroBoy を組み立ててみた。

動かしてみる

早速、動かしてみたい!

倒立振子をするロポットの作り方は以下のチュートリアルに乗っている。 - Tutorial: Building BALANC3R - Robotsquare

バランスをとりながら倒立するロポットは 2 種類あるみたい。 - BALANCE3R - GyroBoy

チュートリアルでは BALANC3R の説明をしているけれども、 BALANCE3R をつくれるのは、LEGO MindStorms Home Edition なので、 私は、GyroBoy を作ることにした(わたしのは Education Edition)

組み立て方は以下のリンクから PDF がダウンロードできる。

出来上がったのは以下のロボット。かっこいい!組み立ての要領が悪く 5 時間かかった。

img

Python で倒立振子する

ev3dev-lang-python には、Balancer が提供さている。さすが。

開発の経緯 - Implement BALANC3R · Issue #130 · rhempel/ev3dev-lang-python

参考になったコード - segway/segway.py at master · laurensvalk/segway

ev3dev-lang-python にまーじされたコード - https://github.com/rhempel/ev3dev-lang-python/blob/d0625b5b1e1fdcdd69b7fa390695613a81191736/demo/BALANC3R

#!/usr/bin/env python3

import logging
from ev3dev.GyroBalancer import GyroBalancer


class BALANC3R(GyroBalancer):
    def __init__(self):
        GyroBalancer.__init__(self,
                              gainGyroAngle=1156,
                              gainGyroRate=146,
                              gainMotorAngle=7,
                              gainMotorAngularSpeed=9,
                              gainMotorAngleErrorAccumulated=3)


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG,
                        format='%(asctime)s %(levelname)5s: %(message)s')
    log = logging.getLogger(__name__)

    log.info("Starting BALANC3R")
    robot = BALANC3R()
    robot.main()
log.info("Exiting BALANC3R")

これを実施すると、RemoteControl が定義されていないということで、エラーする

LEGO MindStorms は リモコンで制御するためのセンサーがあるのだけれども、 教育版にはリモコンセンサはついていない。なので、以下のソースをいじって REMOTE CONTROL にかかわる部分を全部削除した!

さあこれでどうだろう・・・立ち上がった!うれしい。

https://www.youtube.com/embed/7Sb4aqrfy3Y?ecver=1

25 Jun 2017, 00:50

ev3dev-lang-python 開発環境(Visual Studio Code)

ev3dev で Python の開発をするには、Visual Studio COde をローカル PC でつかうのがよさそう。

サーバ上でコーディングすると、サーバからのレスポンスが遅くてイライラする。

なので、ローカルで編集したファイルをサーバにアップロードする方式のほうがよさそう。

VS Code なら ftp-sync という拡張機能があり、保存のたびに サーバとローカルのフォルダの同期が走る。

Visual Studio Code の設定メモです。

環境

  • Ubuntu 16.04 LTS
  • Visual Studio Code 1.13.1

Visual Studio Code

VS Code の本体を手に入れる。

deb をダウンロードして、以下でインストール。

$ sudo dpkg -i code_1.13.1-1497464373_amd64.deb

anaconda

anaconda をつかって、専用の環境を用意する。

# ev3 環境を作成
$ conda create -n ev3
$ activate ev3

# python をインストール
$ conda install python

VS Code の ファイル > 基本設定 > 設定を選択。

ユーザ設定ファイル setting.json が作成される。setting.json に python のパスを追記する。

"python.pythonPath": "/home/tsu-nera/anaconda3/envs/ev3/bin/python",

ev3dev-lang-python

ev3dev ライブラリをインストール。

$ git clone https://github.com/rhempel/ev3dev-lang-python.git
$ cd ev3dev-lang-python
$ python setup.py

pylint

pylint をインストールすることで、エラーチェックを有効化。

$ conda install pylint

autocomplete

ev3dev-lang-python の API のコード補完ができない。

PyCharm だとこの辺ができるんだけどな。。。。解決策探し中。

拡張機能

python

Python で開発するための必須機能。

ftp-sync

VS Code のキモの拡張機能。sftp を利用してサーバとフォルダを同期する。

以下のように、ftp-sync.json を設定する。

sftp は port22 に変更することに注意。remotePath は同期したいサーバ上のフォルダ。

{
    "remotePath": "./experimentals",
    "host": "ev3dev.local",
    "username": "robot",
    "password": "maker",
    "port": 22,
    "secure": false,
    "protocol": "sftp",
    "uploadOnSave": true,
    "passive": false,
    "debug": false,
    "privateKeyPath": null,
    "passphrase": null,
    "ignore": [
        "\\.vscode",
        "\\.git",
        "\\.DS_Store"
    ],
    "generatedFiles": {
        "uploadOnSave": false,
        "extensionsToInclude": [],
        "path": ""
    }
}