授業時に配布した資料 (EV3を動かしてみる http://yakushi.shinshu-u.ac.jp/robotics-ev3/ ) をアップしました。 下記のメモより詳しく書いてあります。
セットアップについては下記を参考に、実際のプログラム例は上記の資料を参考にしてください。
目次
http://www.ev3dev.org/docs/getting-started/ を参考に。
2018年4月現在のDebian本家の安定バージョン(stretch)と同じstretch版を使ってみる
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で取得したアドレスを確認しておく。
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:~$
(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追記)
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秒。
>>> 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')
と同じ。
>>> 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) ...
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
ここで./は現在のフォルダ(ディレクトリ)を表す(ファイル名だけだとパスがつながっていないのでエラーになる)
https://ipython.org/ipython-doc/1/interactive/public_server.html を参考に
robot@ev3dev:~$ sudo apt-get update robot@ev3dev:~$ sudo apt-get install ipython-notebook
nbserverという名のプロフィールを作ってみる
robot@ev3dev:~$ ipython profile create nbserver
この命令を実行すると ~/.ipython/profile_nbserver というディレクトリが作成される。 その中の ipython_notebook_config.py というファイルを編集して、 とりあえず以下の指定をする。
c.NotebookApp.ip = '*' c.NotebookApp.open_browser = False
robot@ev3dev:~$ ipython notebook --profile=nbserver
でサーバを起動すると、パソコンのブラウザから http://192.168.2.30:8888/ のようなアドレスでnotebookにアクセスできる (ev3のIPアドレスが192.168.2.30の場合)。デフォルトのポートは8888。
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 あたりを参考に。
notebook を起動する
robot@ev3dev:~$ jupyter-notebook
これでパソコンのブラウザを開いて http://192.168.2.30:8888/ のようなURLでアクセスできる。 デフォルトのポートは8888番(設定ファイルで変更可能)。
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() # モータ停止
上の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からのこのページのだいたいの訪問者数: 本日2 昨日1 合計30626