授業時に配布した資料 (EV3を動かしてみる http://yakushi.shinshu-u.ac.jp/robotics-ev3/ ) をアップしました。 下記のメモより詳しく書いてあります。

セットアップについては下記を参考に、実際のプログラム例は上記の資料を参考にしてください。

目次

参考サイト

準備

http://www.ev3dev.org/docs/getting-started/ を参考に。

OSのイメージをダウンロード

https://github.com/ev3dev/ev3dev/releases/download/ev3dev-jessie-2015-12-30/ev3-ev3dev-jessie-2015-12-30.img.xz

https://github.com/ev3dev/ev3dev/releases/download/ev3dev-jessie-2016-12-21/ev3dev-jessie-ev3-generic-2016-12-21.zip

https://github.com/ev3dev/ev3dev/releases/download/ev3dev-jessie-2017-02-11/ev3dev-jessie-ev3-generic-2017-02-11.zip

https://github.com/ev3dev/ev3dev/releases/download/ev3dev-jessie-2017-06-09/ev3dev-jessie-ev3-generic-2017-06-09.zip

2018年4月現在のDebian本家の安定バージョン(stretch)と同じstretch版を使ってみる

https://oss.jfrog.org/list/oss-snapshot-local/org/ev3dev/brickstrap/2018-04-22/snapshot-ev3dev-stretch-ev3-generic-2018-04-22.img.xz

microSDまたはmicroSDHCにコピー

microSDXCは使えない。microSDのデバイス名が /dev/sdb とすると、以下のようにddでイメージをメディアに書き込む。

xzcat ~/Download/ev3dev-jessie-ev3-generic-yyyy-mm-dd.img.xz | sudo dd bs=4M of=/dev/sdb

xzcat ~/Download/snapshot-ev3dev-stretch-ev3-generic-2018-04-22.img.xz | sudo dd bs=4M of=/dev/sdb

デバイス名が不明な場合は cat /proc/partitions などのコマンドで調べる。 USB経由で接続した場合は /dev/sdb のようなUSBメモリと同じようなデバイス名に、SDカードスロットに入れた場合は /dev/mmcblk0 のようなデバイス名になっていることが多い。

起動

microSDを本体のカードスロットにセットして電源ON(真ん中の四角いボタンを押す)。microSDが入っていれば、本体のOSではなくmicroSDのOS(ev3dev)が起動する

ネットワークの接続

wifiのドングルを使うのがおそらく最も簡単。 brickmanのメニューが表示されたら、 「Wireless and Networks」→「Wi-Fi」で無線ネットワークを選ぶ。 「Powered」をチェックすると「StartScan」で無線ネットワークをスキャンできる。 無線ネットワークを選択して接続できたら、ディスプレイ上部に表示されている、DHCPで取得したアドレスを確認しておく。

sshでログイン

IPアドレスが192.168.2.30の場合、パソコン側から

ssh robot@192.168.2.30

でログインできる(デフォルトのUIDは「robot」、パスワードは「maker」)。 Windowsの場合はTeraTermなどを使えばよい。

localhost:~$ ssh robot@192.168.2.30
robot@192.168.2.30's password: 
             _____     _
   _____   _|___ /  __| | _____   __
  / _ \ \ / / |_ \ / _` |/ _ \ \ / /
 |  __/\ V / ___) | (_| |  __/\ V /
  \___| \_/ |____/ \__,_|\___| \_/

Debian jessie on LEGO MINDSTORMS EV3!

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Dec 26 10:13:57 2016 from 192.168.2.21
robot@ev3dev:~$ 

Python でインタラクティブに動かす

python-ev3devのインストール

(ev3dev-jessie-2017-06-09版ではイメージに含まれているのでインストール不要)

python-ev3devをインストールする。(以前はOSイメージに入っていたはずだが、ev3dev-jessie-2017-02-11版には含まれていない。2017-04-24追記)

robot@ev3dev:~$ sudo apt-get install python-ev3dev

最近のOSイメージにはもともと収録されているので、インストール不要。(2018-04-24追記)

pythonの起動

python3 というコマンドでpython 3.5を起動できる。

robot@ev3dev:~$ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

pythonコマンドでは、最近のev3devがサポートしていない python 2.7 が起動してしまうので、特に理由がない限り python3 を使う。

モジュールのインポート

>>> import ev3dev.ev3 as ev3

モータのインスタンスを生成

>>> m = ev3.LargeMotor('outA')

モータの各ポート名は、'outA' 'outB' 'outC' 'outD'。 小さい方のモータは、MediumMotor。

モータ・クラスについては http://www.ev3dev.org/docs/drivers/tacho-motor-class/ を参考に。

モータのリセット

>>> m.reset()

モータを回転させる

モータのリセット後は、duty_cycle_sp(デューティ・サイクルのセットポイント)とspeed_spが0になっている。 回転させるためには、duty_cycle_spに0以外の-100から100までの値を指定し、 speed_spに 0から1050 -1000から+1000までの値を指定する。 最新のev3devでは、run-direct以外では常にレギュレーションがONになっているので、 duty_cycle_spを指定せずに、speed_spだけを指定する。 参考URL: https://sites.google.com/site/ev3python/learn_ev3_python/using-motors

>>> m.run_forever(speed_sp=500)

あるいは、以下でも同じ動作。

>>> m.speed_sp=500
>>> m.run_forever()

モータを止める

>>> m.stop()

モータの止め方は'coast' 'brake' 'hold'の3種類。デフォルトは'coast'。指定の方法は、

>>> m.stop(stop_action='brake')

のように値を渡すか、

>>> m.stop_action='brake'
>>> m.stop()

のようにする。

%% 新しいカーネル(Linux ev3dev 4.4.9-11-ev3dev-ev3)では、stop_commandがstop_actionに、 stop_commandsがstop_actionsに変更になっている。また、speed_spの値を指定しておかないとモータは回らない(-1000〜1000)。%%

モータを一定時間回す

>>> m.run_timed(time_sp=3000, speed_sp=500, stop_action='brake')

timeで指定する時間の単位は1/1000秒。

モータを一定時間回す(sleep関数を使う方法)

>>> import time
>>> m.run_forever(speed_sp=500)
>>> time.sleep(3)
>>> m.stop()

sleep関数を使うためにtimeモジュールをインポート。sleepで指定する時間の単位は1秒。

モータを一定時間回す(タイマ関を使う方法)

上記のsleepを使った方法だと、sleepしている間は他の命令は実行できません。 他の命令を実行したい場合には次のようにタイマを使えば簡単です。

>>> import time
>>> ts = ev3.TouchSensor('in1')
>>> t0 = time.time()
>>> m.run_forever(speed_sp=500)
>>> while time.time()-t0 < 3:
>>>     if ts.value() == 1:
>>>         m.stop()
>>> m.stop()

モータを特定の角度だけ回す

>>> m.run_to_rel_pos(position_sp=360, speed_sp=500, stop_action='hold')

これは

>>> m.reset()
>>> m.run_to_abs_pos(position_sp=360, speed_sp=500, stop_action='hold')

と同じ。

センサーの種類

  • TouchSensor タッチセンサ
  • ColorSensor カラーセンサ
  • UltrasonicSensor 超音波センサ
  • GyroSensor ジャイロセンサ
  • SoundSensor NXTのサウンドセンサ
  • LightSensor NXTのライトセンサ
  • InfraredSensor EV3の赤外線センサ(距離測定用)

超音波センサを使う

>>> us = ev3.UltrasonicSensor()
>>> us.value()
112

デフォルトの単位はcm(US-DIST-CM)のはずだが、なぜかmmで値が表示されている。

光センサを使う

モード一覧

>>> cs=ev3.ColorSensor()
>>> cs.modes
['COL-REFLECT', 'COL-AMBIENT', 'COL-COLOR', 'REF-RAW', 'RGB-RAW', 'COL-CAL']

デフォルトのモードはCOL-REFLECT。

白い紙の1cmほど上で測ってみると

>>> cs.value()
58

黒い紙だと大抵ひと桁の値になる。

タッチセンサを使う

>>> ts = ev3.TouchSensor('in3')
>>> ts.value()
0
>>> ts.value()
1

タッチセンサが押されていない状態で0、押された状態で1。

ジャイロセンサを使う

>>> gs = ev3.GyroSensor()
>>> gs.modes
['GYRO-ANG', 'GYRO-RATE', 'GYRO-FAS', 'GYRO-G&A', 'GYRO-CAL']
>>> gs.mode
u'GYRO-ANG'
>>> gs.value()
-135
>>> gs.mode = 'GYRO-RATE'  # モードの変更
>>> gs.value()
0

応用

>>> import ev3dev.ev3 as ev3
>>> import time
>>> ts = ev3.TouchSensor('in1')
>>> cs = ev3.ColorSensor('in2')
>>> while ts.value() == 0:
...     if cs.value() > 30:
...         m.run_forever(speed_sp=500)
...     else:
...         m.stop(stop_action='brake')
...     time.sleep(0.1)
...

pythonの終了

control-D

スクリプトの作成と実行

スクリプトの編集

エディタ(nanoまたはvi)で次のようなスクリプトを作る。ファイル名は例えばtest.pyのようにpyという拡張子を付けておくと便利。

robot@ev3dev:~$ nano test.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import ev3dev.ev3 as ev3
import time

motor_left = ev3.LargeMotor('outA')
motor_left.run_forever(speed_sp=500)
time.sleep(3)
motor_left.stop(stop_action='brake')

スクリプトを実行可能に

robot@ev3dev:~$ chmod +x test.py

スクリプトの実行

robot@ev3dev:~$ ./test.py

ここで./は現在のフォルダ(ディレクトリ)を表す(ファイル名だけだとパスがつながっていないのでエラーになる)

ipython notebookで使う (obsolete)

https://ipython.org/ipython-doc/1/interactive/public_server.html を参考に

ipython-notebookのインストール

robot@ev3dev:~$ sudo apt-get update
robot@ev3dev:~$ sudo apt-get install ipython-notebook

ipythonの設定

nbserverという名のプロフィールを作ってみる

robot@ev3dev:~$ ipython profile create nbserver

この命令を実行すると ~/.ipython/profile_nbserver というディレクトリが作成される。 その中の ipython_notebook_config.py というファイルを編集して、 とりあえず以下の指定をする。

c.NotebookApp.ip = '*'
c.NotebookApp.open_browser = False

notebook serverの起動とアクセス

robot@ev3dev:~$ ipython notebook --profile=nbserver

でサーバを起動すると、パソコンのブラウザから http://192.168.2.30:8888/ のようなアドレスでnotebookにアクセスできる (ev3のIPアドレスが192.168.2.30の場合)。デフォルトのポートは8888。

jupyter notebook で使う

Jupyter notebook のインストール

Debian jessieにはjupyterパッケージがないので jessie-backportsからインストールする。

まず、/etc/apt/sources.list.d/jessie-backports.list というファイルを新規に作成して次の一行を書いておく。

deb http://ftp.jp.debian.org/debian jessie-backports main contrib non-free

updateした後、jupyter-notebookというパッケージをインストールすれば、とりあえずjupyterでpythonを使う上で必要なものも自動的にインストールしてくれる。

robot@ev3dev:~$ sudo apt-get update
robot@ev3dev:~$ sudo apt-get install -t jessie-backports jupyter-notebook

次に設定ファイルを作成して編集しておく。

robot@ev3dev:~$ jupyter-notebook --generate-config

とすると /home/robot/.jupyter/jupyter_notebook_config.py というファイルが生成されるのでこれを編集。 とりあえずリモートから使うために以下の項目を設定しておく(もとのファイルではコメントアウトされている)。

c.NotebookApp.ip = '*'
c.NotebookApp.notebook_dir = '/home/robot/jupyter'
c.NotebookApp.open_browser = False

ここで指定した作業用のディレクトリを作成しておく。

robot@ev3dev:~$ mkdir ~/jupyter

IPアドレスやパスワードでアクセスを制限したい場合は、 http://jupyter-notebook.readthedocs.io/en/latest/public_server.html あたりを参考に。

Jupyter notebookを起動

notebook を起動する

robot@ev3dev:~$ jupyter-notebook 

これでパソコンのブラウザを開いて http://192.168.2.30:8888/ のようなURLでアクセスできる。 デフォルトのポートは8888番(設定ファイルで変更可能)。

MQTTを使った通信

MQTTという軽量プロトコルを使った通信が http://www.ev3dev.org/docs/tutorials/sending-and-receiving-messages-with-mqtt/ で紹介されている。

MQTTではpublisher(出版者)が発するメッセージをbroker(仲介者)がsubscriber(購読者)へ配信する。 MQTTは、EV3間の通信だけでなく他のデバイス間でもいろいろと使える。

ブローカのインストール

サーバソフト(ブローカ)としてオープンソースのmosquittoを使う。 ネットワークに接続されている機器ならどれにインストールしてもかまわないが、 以下では、 一方のEV3を他方のEV3のリモコンとして使う簡単な例を挙げ、 EV3の一つをbrokerとしても使う方法を紹介する (他のEV3やパソコンにインストールする必要はない)。

上のev3devのサイトではpublisher側(リモコン側)にブローカをインストールしているが、 パソコンなどからでも直接コントロールできるように、リモコン側のEV3ではなく実際に動く側のEV3にブローカをインストールする(もちろんリモコン側にブローカをインストールした場合でも、そのブローカのEV3を起動しておけば、パソコンともう一方のEV3の間の通信は可能)。

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

インストールが完了すればサーバが立ち上がる。チェックするには

robot@ev3dev:~$ sudo service mosquitto status

デフォルトのポートは1883番。

クライアントのインストール

ブローカにメッセージを送信したり、ブローカからメッセージを購読したりするデバイスやそのためのソフトをMQTTのクライアントと呼ぶ。ブローカ(サーバ)をインストールしたEV3を同時にクライアントとして動作させることも可能。

pythonからMQTTを使うために、各EV3(とパソコン)にpahoのpython用ライブラリをインストール。(その前にpythonパッケージをインストールするためのツールとしてpipをインストールしておく)

robot@ev3dev:~$ sudo apt-get install python3-pip
robot@ev3dev:~$ sudo pip3 install paho-mqtt

パソコン上にもpaho-mqttをインストールしておくと便利。

paho-mqtt詳細については、 https://pypi.python.org/pypi/paho-mqtt を参照のこと。

サンプルプログラム

一方のEV3に接続したモータをアクセルのように使って他方のEV3のモータのスピードをコントロールするプログラムを作ってみる。ただしブローカはコントローラ側(パブリッシャー側)受信側のEV3で動作させている。

パブリッシャー(送信側)のプログラム

#!/usr/bin/python3
import paho.mqtt.client as mqtt  # pahoのライブラリをインポート
import ev3dev.ev3 as ev3
import time

ts = ev3.TouchSensor('in1')   # プログラム停止用のタッチセンサ
m = ev3.LargeMotor('outA')    # コントローラとして使うモータ
m.reset()
speed_A = 0     # 相手側モータのspeed_spとして送信する値を格納するための変数

client = mqtt.Client()        # MQTTのクライアントを生成
client.connect("192.168.2.30",1883, 60) # ブローカ(192.168.2.30)の1883番portに接続
                                     # (60秒以上接続がないと切断)

while (ts.value() == 0):      # タッチセンサが押されていない間だけ繰り返し
  pos = m.position            # 現在のモータのポジションを取得

  if (pos > 90):
    speed_A = 900
  elif (pos < -90):
    speed_A = -900
  else:
    speed_A = pos*10   # ポジションからspeed_spの値を計算(90度で最大900になるようにした)

  client.publish("ev3/outA", speed_A)  # "ev3/outA"というトピックスでspeed_Aの値をブローカに送る
  time.sleep(0.01)

client.disconnect() # 切断

サブスクライバ(受信側)のプログラム

#!/usr/bin/python3

import paho.mqtt.client as mqtt
import ev3dev.ev3 as ev3
import time

ts = ev3.TouchSensor('in1')  # プログラム停止用のタッチセンサ
m = ev3.LargeMotor('outA')   # 動作確認用のモータ
m.reset()

def on_connect(client, userdata, flags, rc):  # ブローカに接続した時に実行される関数(コールバック関数)を定義しておく
  print("Connected with result code "+str(rc))
  client.subscribe("ev3/outA")                # "ev3/outA"というトピックスを購読
  m.run_direct()                              # モータの属性変更が即時に反映されるモード

def on_message(client, userdata, msg):        # メッセージを受け取った時に実行される関数(コールバック関数)を定義しておく
  m.speed_sp = int(msg.payload)               # payloadという変数にメッセージが入る
                                                # メッセージ自体はutf-8の文字列なので int に変換しておく

client = mqtt.Client()            # MQTTのクライアントを生成
client.on_connect = on_connect    # 上で定義したコールバック関数を渡す
client.on_message = on_message    # 上で定義したコールバック関数を渡す

client.connect("localhost",1883, 60)  # ブローカ(自分自身なのでlocalhost)の1883番ポートに接続 (Keep Alive は60秒)
client.loop_start()               # メッセージ受信ループの開始

while(ts.value() == 0):  # タッチセンサが押されていない間、繰り返し
  time.sleep(0.01)

client.loop_stop()  # 受信ループを停止
client.disconnect() # 接続を切断
m.stop()            # モータ停止

MQTTでパソコンからEV3を操作する

上のsubscriber側のプログラムはそのまま使える。

publisher側のプログラムをパソコンで作成してもよいが、mosquitto-clients というツールを使えばシェルから(コマンドラインで)直接メッセージをパブリッシュできる。

まずはパソコンに mosquitto-clients をインストール

$ sudo apt-get install mosquitto-clients

メッセージを送ってみる

$ mosquitto_pub -h 192.168.2.30 -t 'ev3/outA' -m "30"

別のターミナルを開いて自分自身でトピックをsubscribeすることもできる

$ mosquitto_sub -h 192.168.2.30 -t 'ev3/outA'

上の mosquitto_pub で値をいろいろ送信してみると、その都度その値がターミナルに表示される。 Control + C で終了。

2016年5月31からのこのページのだいたいの訪問者数: 本日17 昨日13 合計6202


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-04-24 (火) 16:12:22 (3d)