ロボットを作る

子供のころ、映画「STARWARS」 を観てワクワクし、ガンプラにドキドキしていた。時間が経つのも忘れてしまう、そんな時間をもう一度、取り戻すために、Raspberry pi を使って、オヤジがロボット作りに挑戦する!

やり始めてみると、なかなか思い通りに行かない。時間の経つのも忘れて悪戦苦闘中。 「こんなちっちゃな Raspberry Pi で、こんなことができるんだ」を日々実感している今日この頃。

購入品

Raspberry Pi2 で、サーボを使って、物体追跡をする。このサイトを見て、

Raspberry Pi サーボモーターとOpen CVで物体追跡カメラ(Meanshift)
ArduinoとAdafruit 16-channel Servo Driverでサーボモーター多数制御

ブツを揃える、


これらを Amazon で Getした。この Qiita のサイトとは異なるブツだが、とりあえず安かったので買ってみた。
カメラは手持ちのヤツを使う。

◆サーボモータを動かす
i2c を有効にする

$ sudo apt-get install i2c-tools
$ sudo raspi-conifig

 > 5. interfacing options
     > P5 I2C

以下のように結線する。サーバを動かすために、Servo Driver基板中央に別途電源をつなぐ(6Vまでらしい)

   RaspPi2   16ch Servo Driver (PCA9685)
  -------------------------------------------------------------
    3.3V○   ○ GND
   I2C SDA○   ○
   I2C SCL○   ○ SCL
           ○   ○ SDA
     GND○   ○ VCC
        ○   ○


結線して、servo_test.py を動かすとちゃんと動いた。
# いかん! サーボモータが、動作電圧:4.8V(~5V) なので、乾電池は3つにしておこう。

PCA9685 16-channel 12bit PWM Fm + I2C-bus LED controller


◆カメラを動かす
$ sudo apt-get install libopencv-dev python-opencv


USBカメラと OpenCV で画像を表示させるサンプルプログラムはググると沢山でてくる。
ただ、最近のサンプルでないと遠回りする。
結局、
import cv2.cv  や CaptureFromCAM ではなく、以下に落ち着いた。(ターミナル上で、ctrl + c で終了)
これを camera.py に保存して、実行
import cv2

cv2.namedWindow("monitor")
vc=cv2.VideoCapture(0)

if vc.isOpened():
   rval, frame = vc.read()
else:
   rval = False

while rval:
   cv2.imshow("monitor", frame)
   rval, frame = vc.read()
   key = cv2.waitKey(10)
   if key == 27:
      break
cv2.destroyWindow("monitor")     

【追記 4/22】
自分の環境で、TightVNCで Raspiを動かしていた。 2行目の namedWindow で以下が出てこけた。

GdkGLExt-WARNING **: Window system doesn't support OpenGL.

で、ググったら、対処方法があったので試してみた。

$ sudo apt-get install libgl1-mesa-dri 
$ sudo reboot

で、これでもダメで、workaround(1) として

$ sudo apt-get install guvcview

をした。workaround(2) は、VNC をTightvnc をやめて、X11vnc 変えるとできるらしい。がやってない。
workaround(3) は、元に戻して、VNCやめて Raspi にモニター直結したら、もちろんOK。

気になっていた

O'Reillyの本
「ゼロから作るDeep Learning
―Pythonで学ぶディープラーニングの理論と実装」

を買ってみた。



レベル感が私にぴったりで、すごく丁寧にわかりやすく、タイトルどおり「ゼロから」説明されている。

まだ半分しか読んでないのだが、じっくり繰り返し読んでいきたい本である。


■RaspberryPi出直し編




訳あって再インストールを。デスクトップ環境が「PIXEL」になってる。

Raspbian Jessie with PIXEL


NOOBS
 Version: 2.1.0
 Release date: 2016-11-29

このOSを使う。
いつもの手順で。
 PCにosをdownload、解凍
 PC上でSDカードに解凍後全部を丸ごとcopy
 RaspberriPi3にSDカードさして、電源on
 Raspbian選んで、画面下の言語選択を「日本語」にして進む
 インストールに若干時間が掛かるが、何事もなく終了

PIXELがなんかいい。デフォルトでの背景がかっこいい。そういわれると軽い(気もする)


sudo apt-get update
sudo apt-get upgrade


■キーボードを日本語設定に。 私のは、ELECOM TK-FCM062

Preferences > Raspberry Pi Configration > Localization タブ
> Keyboad: 
  Country: Japan
  Variant: Japanese(PC98-xx Series)

を選択して終わり。

■日本語入力を

■ python3 を jupyter で
やりたいのは、jupyter notebook で、numpy、matplotlib で Deep Learning のお勉強
「ゼロから作る Deep Learning」のため。 python3 と numpy はもとから入ってた。



$ sudo pip3 install jupyter

※sudo でないと、permittion error で終わる。

$ sudo pip3 install matplotlib

で、確認
$ jupyter notebook

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
x=np.arange(0,5,0.1)
y=np.cos(x)
plt.plot(x,y)

動いた。


RaspberryPi3 に、やっと到着した USB マイクを動かしてみる。




 このUSBマイクは、型号:MI-305 made in China で。

ネット情報をもとに、以下すすめる。

差し込んで、立ち上げただけ。
$ lsusb
Bus 001 Device 006: ID:xxxx:xxxx C-Media Electronics, Inc. CM108 Audio Controller
 :

$ arecord -l
カード 1: Device [USB PnP Sound Device], デバイス 0: USB Audio [USB Audio]
 # USBマイクの カード番号:1/デバイス番号:0

$ amixer sget Mic -c 1
 # マイク音量の確認。 カード番号: 1

$ amixer sset Mic 16 -c 1
 # マイク音量の設定をMAXの 16

$ arecord -M -d5 -twav -fdat voice.wav -D plughw:1
  # マイク入力音声をWAVファイルへ保存
 1.サンプリングフォーマット: 48kHzステレオ(-fdatで DAT品質)
 2.5秒間(-d5で 5秒)
 3.保存ファイル名: voice.wav
 4.使用する PCM 


このあと、aplay で、voice.wav を再生すると、録音できてた。
とりあえず簡単に動いた。

続きを読む

Raspberry Pi3 に Ubuntu を入れる。



RaspPi3をネットで買うときに、ついでに UDB wifi ドングルを買ってしまったが、Pi2と違い Pi3 は Wifi 付いてた(on board)。しまった。

Ubuntu の中でも、RaspPi3対応な、Ubuntu MATE を以下からとってくる。
https://ubuntu-mate.org/download/

7-zip で、xz ファイルを解凍して、sdカードに書き込む。


■ disk容量

Ubuntu MATEインストール後は、本来のSDカード容量に関係なく、8G程度になるらしい。俺のは16Gなのに有効に使えてない。
先達さんのWebに書いてあった手当を行う。

$ sudo fdisk /dev/mmcblk0
  Command (m for help): d
  Partition number (1,2, default 2): 2
  Command (m for help): n
  Select (default p): p
  Partition number (2-4, default 2): 2
  First sector (133120-120946687, default 133120): (Enter)
  Last sector, +sector of +size{K,M,G,T,P} (133120-120946687, default 120946687): (Enter)
  Command (m for help): w
$ sudo reboot
<再起動>
$ sudo resize2fs /dev/mmcblk0p2
$ df -kh で確認


■ 日本語入力
OSインストール後にGUI画面から日本語を選ぶと「表示」は日本語にあるが、「入力」ができない。

システム > 設定 > ユーザ向け > 言語サポート

を開くと ”言語サポートが完全にはインストールされていません” と出てくるのでインストールを。
インストール完了後に キーボード入力に使うIMシステム を fcitx にする。
ログインしなおす。





届いた!

image

























箱を開ける。
ケーブルとか and タッチスクリーンが。

image













































マニュアル的なのがなかった。箱の裏にURLが。

Raspberry Pi 7” Touchscreen Display
https://www.element14.com/community/docs/DOC-78156 

ここを見ながら組み立てる。ただ、4までの接続&スタンドオフ止め済みだった。

image


























残りのリボンケーブル接続、ジャンパーの赤黒をつなげて、とりあえずタッチスクリーンにつながずに、手持ちモニターで立ち上げる。


sudo apt-get update
sudo apt-get upgrade
タッチパネルの仮想キーボードも入れておく
sudo apt-get install matchbox-keyboard


このタッチスクリーンが 800×480 で、自動的に認識させるために、

sudo raspi-config
 8 Advanced Options
   A1 Overscan 
     Disable 
を選んで、保存して再起動!



このブログを始めるきっかけになった

「Raspberryで学ぶ電子工作」



に続く、新しい本がついに出た!!!

「実例で学ぶ Raspberry Pi 電子工作」
 



んで、前作と同様にサポートページもある。

実例で学ぶRaspberry Pi電子工作 作りながら応用力を身につける サポートページ
http://bluebacks.kodansha.co.jp/bsupport/rspi2.html

前作のサポートページでは、出版後にリリースされた Rasp Pi2の情報や、新しい情報がUPDATEされていく。いきなり ググらなくてもいいので助かる。
今回も新書の購入とともに、このサポートページを追いかけていく。

ずいぶん間があいてしまった。
サンプルプログラムの OpenGL を Raspi 自身で動かそうとしたが、私のプログラミング能力ではできなかった。



よって、もとのサンプルどおりに

 A. センサー& Webサーバ:Raspi
 B. 3D表示(OpenGL)側:別のPC(Ubuntu)

にわけて 3D表示させてやった。
サンプルの注意どおりに webサーバの ip変えるだけで、うまくいった。すげぇ、かっこいい!

もともと MPU-6050 センサーから出力される数値が、机の上で制止している状態(のはず)でも、 server.py で出力される毎に、微妙に変化しているのが、3D 画面上での 微妙に振るえてる感じで表現されている。





RaspberryPi と MPU-6050 の組み合わせでマネしたページ。

Interfacing Raspberry Pi and MPU-6050

Reading data from the MPU-6050 on the Raspberry Pi



まず、準備として I2C を使えるようにする。

$ sudo vi /etc/modules
 i2c-dev を追記
$ sudo apt-get install i2c-tools
$ sudo raspi-config
  8 Advance Options
   ->  A7 I2C

MPU-6050 を

 Pin 
  1 - VCC

  3 - SDA
  5 - SCL
  6 - GND

に接続する。



raspi を再起動して、MPU-6050 を認識できてるかを確認。

  $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
 $ 


先のWebに載っていた pythonプログラムを完コピし、SMBus(1) に変えただけ。

bus = smbus.SMBus(1) # or bus = smbus.SMBus(1) for Revision 2 boards

おもむろに動かしてみる。

$ sudo python test.py 
gyro data
---------
gyro_xout:  -278  scaled:  -3
gyro_yout:  175  scaled:  1
gyro_zout:  -209  scaled:  -2

accelerometer data
------------------
accel_xout:  560  scaled:  0.0341796875
accel_yout:  276  scaled:  0.016845703125
accel_zout:  -16792  scaled:  -1.02490234375
x rotation:  0.941128353108
y rotation:  -1.90980354956

 でけた。中身をすこし研究しよう。



以前、失敗した LCD AQM0802(秋月電子) の利用。リベンジした。

失敗したときの記事

といっても結果的にはハンダ付けをやり直しただけだ。

著者 Webにもあるとおり LCDの9本の足の間はピッチが狭いだけに、初心者の私には難しかった。

"はんだ吸取線"を買って、隣同士が引っ付いたのを吸い取りながら、四苦八苦、何とかハンダ付けを終えた。

おもむろに、

$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

おおっ、認識した。3e がその印。

07-02-LCD.py を実行し、Hello World を液晶に表示させた。。。はずが、
黒くなるばかり。。。あれ???


説明書のコントラスト設定を データシートの初期設定例をみながら

0x70,0x56 を 0x77,0x54 に変えてみて、短い文字を流すと見れた。

$ python 07-02-LCD.py 'test'

ただ、液晶画面の2行にわたる文字になると、今度は文字が薄くなる。なんで???

よくわからんので、もう一度ハンダを付け直した。団子の部分を解消したり、半分付いてなさそうなところをしっかり付けたり。”ハンダ吸取線”を駆使しながら、再構築した。

すると。。。 うまくいった。ハンダ付けに苦労したが、ちゃんと付いていれば液晶にくっきり文字が出る(当然なんだろうが)。ちょっと嬉しかった。

コントラスト設定を元に戻しても、くっきり文字が出た。



 

USBカメラを買った。

ELECOM
UVC WEBカメラ
UCAM-C0220FEシリーズ 



$ sudo apt-get install motion
$ lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 004: ID 04b4:aef9 Cypress Semiconductor Corp. 
Bus 001 Device 005: ID 1a81:2004 Holtek Semiconductor, Inc. 
Bus 001 Device 006: ID 056e:7016 Elecom Co., Ltd 

$ sudo motion

カメラを機動したあと、ブラウザで

http://localhost:8081

とするとカメラに写る自分が。

ただ、default で、/tmp/motion/ の下に沢山の jpg ファイルを生み出す。
これを止めるのに、

/etc/motion/motion.conf の

# output_normal on
output_normal off

と off に変更した。
これで jpg ファイルは無くなった。

Flash(swf)ファイルが生成される。再生するツールとして、gnash を入れる。

$ sudo apt-get install gnash

とりあえず動いた。





 

こちらのネタもしっかりとおさえておこう。


いまさら聞けない加速度センサー入門
http://monoist.atmarkit.co.jp/mn/articles/0903/24/news112.html

いまさら聞けないジャイロセンサー入門
http://ednjapan.com/edn/articles/1406/09/news014.html



そして買うならこれか。

◆MPU-6050 三軸加速度センサー、三軸ジャイロセンサー

MPU-6050 使用 3軸ジャイロスコープ・3軸加速度センサー モジュール

新品価格
¥430から
(2015/5/1 07:28時点)




Raspberry Piで動かすのに参考になる Web ページ。

Interfacing Raspberry Pi and MPU-6050

Reading data from the MPU-6050 on the Raspberry Pi


このセンサーは先達さんが大勢おられるのが心強い。

2015/4/28 Amazonで購入。480円。
GWにでも動かしてみるか。 

気になっていた O'REILLY 「実践 機械学習システム」をやっと買った。




これからちょっとずつ読み進めていこう。
まずは「第1章 Pythonではじめる機械学習」 から。

この本は、Pythonのライブラリである Numpy、Scipyを用い、scikit-learn で機械学習を学びます。 

準備として、


ソースコードを利用

この ch01 配下の .py をダウンロードして使う。

 ch01/
  data/
    web_traffic.tsv 
  gen_webstats.py
  analyze_webstats.py
  performance_test.py 


現状(2015/4/27時点)、このweb_traffic.tsv は、
1.5.1 データを読み込む で紹介されている不適切な値 nan は含んでいない。

サンプルプログラムの .py ファイル内の __file__ は、実際の環境に合わせて編集するべきものと、勝手に思い込んでいたが、実際には .py を実行するディレクトリに data フォルダを作ってやれば、そのまま実行できた。


analyze_webstats.py の実行中に、polyfitで warning が出たが、とりあえず実行は終わり png ファイルも生成された。

>>> f100 = sp.poly1d(sp.polyfit(x, y, 100))
/usr/lib/pymodules/python2.7/numpy/lib/polynomial.py:560: RankWarning: Polyfit may be poorly conditioned
  warnings.warn(msg, RankWarning)
>>> 

SciPyの numpy.polyfit

に、この原因について、
High-order polynomials may oscillate wildly:
と書かれている。

境目となるのは、コマンドラインから確認すると、

>>> f33 = sp.poly1d(sp.polyfit(xp, y, 33))
>>> f34 = sp.poly1d(sp.polyfit(xp, y, 34))
>>> f35 = sp.poly1d(sp.polyfit(xp, y, 35))
/usr/lib/pymodules/python2.7/numpy/lib/polynomial.py:560: RankWarning: Polyfit may be poorly conditioned
  warnings.warn(msg, RankWarning)
>>> 

であった。analyze_webstats.py の f100 の 100 を 30 に下げて、.py を実行。 あれ? 変わらず。
30 をさらに下げていくと、結局、後半の polyfit は 10 でも引っかかるようだ。


で、肝心の最適なモデルを決めることについて、本では 次数 2 のモデルが誤差が最小となっているが、analyze_webstats.py を実行する毎に変化する。次数 1 のときもあれば、次数 10 のときもある。

あれ? なんか変だな。

とりあえず、ひと通り進めてから考えよう。第1章でコケてるわけにはいかない。
 


I2C接続の練習で利用したのは、

「高精度・高分解能 I2C・16bit温度センサーモジュール」 ADT7410 を使用

I2Cバスアドレスを選択できるようで、デフォルトでは 0x48。
基盤の J4,J3 をハンダ付けすることで他に3つ選べるようだが、デフォルトのまま利用した。

仕様書に
 「温度分解能(0℃を基準とした+/-符号ビットを含む)
 0.0078℃(16bit設定時)/0.0625℃(13bit設定時)」

とあって、今回プログラム内でも 13bit になっている。


プログラムのなかに

 address_adt7410 = 0x48
 register_adt7410 = 0x00

と2つの”アドレス”が出てくるが、いまいち何のために分かれているいるのか?だったが、本を読むとちゃんと書いてある。

 前者: デバイスの場所
 後者: 取得したいデータ or 保存したいデータの場所



 


readadc を理解するために MCP3208 の仕様を確認しておこう。


MCP3208資料(日本語)


mcp3208_1
図5-1 MCP3204 あるいはMCP3208 との通信


・通信を開始: CS:High⇒Low    ※デバイスとの通信開始するには CSを Lowに。
・スタートビット(1bit) CS:Low + Din:High で、受取る最初のクロックは、スタートビット
・制御ビット(4bit): 
      SGL/DIFF(1bit): [1]シングルエンドモード ・・・
                  [0]差動入力モード・・・
      D0,D1,D2(3bit): 使用入力チャネル ※今回 CH0 なので [0,0,0]

・アナログ入力のサンプリング開始は、開始ビット後、4 番目クロックUP。
・サンプリング終了は、開始ビット後、5番目のクロックDOWN


ここでプログラムの以下の部分(13~15行目)をみると

 commandout = adcnum
 commandout |= 0x18
 commandout <<= 3

adcnum は、CH0 を使用するので 0 。
加えることの 0x18 = 0001 1000 でスタートビットと制御ビットになる。

3bit 右からづらすと、
1100 0000

ここまで、
0
0001 1000
1100 0000
となった。


16    for i in range(5):
17        # LSBから数えて8ビット目から4ビット目までを送信
18        if commandout & 0x80:
19            GPIO.output(mosipin, GPIO.HIGH)
20        else:
21            GPIO.output(mosipin, GPIO.LOW)
22        commandout <<= 1
23        GPIO.output(clockpin, GPIO.HIGH)
24        GPIO.output(clockpin, GPIO.LOW)


1巡目の18行目では、
     1100 000
          & 論理積
     1000 000
=   1

になる。1巡目22行目で、1bitシフトして

   1 1000 0000

になって、2巡目に

   1 1000 000
          & 論理積
   0 1000 000
=    1

で、3巡目

  11 0000 000
          & 論理積
  00 1000 000
=     0

結果的に、5巡すると、1,1,0,0,0 になる。


先々週からネットやら店舗やらで、本に出てきたパーツやらと、道具(はんだゴテやはんだも)を買った。
開梱する間もなく、どんどん溜まって、妻に「いくつ届くの?」とぼやかれながら、苦笑いの日々を送ってきた。


ダンボールたち・・・・

IMG_1015





週末に開梱して、並べてみると、こんな感じに。

IMG_1016



が、しかーーーし、肝心の Raspberry Pi がまだ入手できていない。

というのも、本を買って読んで、時間がかかっているうちに B+ の次のバージョンである「Raspberry Pi B2」が、2015年2月にリリースされ、当然それを注文したのだが、品薄で、現在入荷待ちの状態なんだ。

のんびり待ってみる。

あっ、あとモニターもないのだけど、使ってないテレビに繋いでみようと思ってる。あまりに不便だったら考えよう。


本で紹介されていた部品一式がつまったキットを購入。
ネットで検索したら amazon に出てきた。


初心者のため、とりあえず本のとおり進めていこうと思ったので、このキットを買った。

が、あとでわかったが、このキットは文字通り「V2」で、本が書かれたときに使用されたのは 「V1」。
若干の違いがあるようだ。
DSC04877DSC04878



そのあたりも
http://raspibb.blogspot.jp/
にフォローされている。至れり尽くせりな感じの本だ。


ずっと気になっていた Raspberry Pi でロボット作ることを考えていた。
Raspberry Piのことは気になっていて、大型書店でいろいろ本を見てきた。
いくつかの本屋を回って、何度も出なおして、時間が過ぎてしまった。

やっと、この本にたどり着いた。

「Raspberry Pi で学ぶ電子工作」 講談社ブルーバックス

この本が出版されたとき、本屋で手にとって第10章にラジコン戦車が出てきたのをみて「これだ!」と思った。
これから Raspberry Piとたわむれる人達におすすめの一冊。




↑このページのトップヘ