卒業研究奇 死闘編 魁鬼屍鬼
前回、重さのサンプリングデータを涙ながらに作成したので、回帰式の推定です。
推定作業には、統計言語R を利用します。;
これは、統計データ処理言語というか、処理環境というかとにかくスクリプトベースで
データのハンドリングと各種統計処理や視覚化が可能なフリーソフトウェアである。
10年ほど前に、某業界で市場データ分析のまねごとをしていたときに覚えたものです。
当時見ていたwikiが存続していた。すばらしい!!困ったときは絶対ここ。
で、回帰式には通常、線形回帰を使うのですが今回は以下のような、非線形っぽい分布に式をあてはめる必要があるのです。
で、以下のサイトを参考にやってみました。
R言語で統計解析入門: 非線形回帰分析 A nonlinear regression analysis 梶山 喜一郎
が、しかしモデルによって計算不能になってしまい唯一可能だったの累乗モデルだけでした。
で、累乗モデルは、Y = a*X^b で式をたてる、a, bの係数を求めるものです。
推定できた重みは以下。
a = 1872000;
b = -1.265;
よって式は、Y=1872000*X^(-1.265)
この式の当てはまり具合を視覚化すると以下
で、式の評価をみてみると
> cor.test( 予測データ, 実績データ , method="pearson")
Pearson's product-moment correlation
data: 予測データ and 実績データ
t = 1406.5, df = 13792, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.9964149 0.9966460
sample estimates:
cor
0.9965324
相関係数が 0.99以上なのでまあよしとする、がもうちょっと改善したいので
ここのマルカート法でモデルで再計算。
Parameters:
Estimate Std. Error t value Pr(>|t|)
a.(Intercept) 1.872e+06 1.383e+04 135.4 <2e-16 ***
b.log(X) -1.265e+00 1.455e-03 -869.5 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 114.1 on 13792 degrees of freedom
Number of iterations to termination: 11
Reason for termination: Relative error in the sum of squares is at most `ftol'.
で、相関分析をする。
Pearson's product-moment correlation
data: 予測データ2 and 実績データ
t = 1407.4, df = 13792, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.9964194 0.9966502
sample estimates:
cor
0.9965367
わずかながら改善したので、式としては
Y = 187169 * X ^(-1.265368)
を血と汗と涙のFSR抵抗値→グラム変換式として採用することにする。(続)
卒業研究奇 死闘編 未開凍土
前回の調査によって、
「センサー値を力に変換する公式な”式"がない」
という衝撃の事実を知ったわたしは、フテくされることなく未開の地を行く決心をした。未開の地のいいところは、どう行こうが誰も文句を言わないところだ。(強がり)
講義、実習、夜勤仕事の合間でやるにはお行儀よくはできないのです。
だからこそ、シンプルにいこうとこの研究にしたのに、なんでこんな目に僕があわな(省略)
まあ、気をとりなおしてまず現状TODOを整理しておこう。
- 自分の環境におけるセンサー値vs力の変換式をつくる
- 実際のアジャストの計測が可能な機器や環境要件をつめる。
- どういうアウトプットにするか考える(この研究で何を言い切るか)
3は1,2をやりながら、それが終わってデータを取り始めてからも何回もラウンドするようなものと認識しておく。具体的には、なにもデータがない状態でも論文を書き始めるということ。
2.について、実際アジャストする際には以下が考慮点でしょうか
- 機器の持ち運び性
- 機器をコントロールするためのPC
- 上記との接続環境(ネットワーク)
- とったデータをその場で、ある程度確認できるようにすること
- 機器を、計測時の物理力に耐えかつ計測できるような構成にしておくこと
なんか箱にいれて持ち運びができて、計測機器とPCを繋げたいけど、実際計測時に電源やLANケーブルがごちゃごちゃするのは実験ノイズとして多きすぎる、バッテリーで動いて、無線LANでつなげたい、ああでも学校の無線LANは接続性が低くて、実用に耐えないしどうしよう。とったデータをエクセルでみるかじゃあcsvで吐き出すか、ああその場でくエクセルなんて起動してグラフつくってデータ確認なんて現実的じゃないしどうしよう。5なんて、ボードにセンサーがささったままなので、コンタクトポイントまで延長しないといけないけど、ジャンパワイヤーとセンサーの平たい端子とまったく適合しないので、コネクターが必要だけどどこで買えばいいのだろう。。と一人ブレスト、まあ観点は洗い出したので、次。
3.は、目下の大問題、変換式のこと。方針は、実際センサーにいくつかの重りを乗せて、そのデータから回帰式を算出するということ。当たり前だけどそれしかない。
しかし、我が家にはそんな都合よく重りがない、で用意したのがこれ。
泣けます。
このペットボトルと軽量カップで、重りを自作する。ペットボトル自体の重さも考慮に入れる必要があるので、環境省の調査資料から、南アルプス天然水のペットボトルの重さも調べる(泣)
南アルプス天然水 500mm 本体24.5 キャップ3.2 ラベル0.6 = 28.3g
南アルプス天然水2000mm 本体46.8 キャップ3.1 ラベル1.4 = 51.3g
で、それらを考慮し、各ペットボトルに軽量カップで水をいれて、以下の重さをFSRでサンプリングする。
128g , 278g, 528g , 806g, 2051g , 4100g
で、取得したデータを電圧に変換して重さとの関係を示したのがこれ。
で、前調べたメーカー資料の右側の10KΩのラインと符号している、よかった。
でもこのままだと回帰式をたてづらいので、FSRの抵抗値に変換する必要がある、変換式は公式資料から変換した電圧をさらにFSRの抵抗値に変換する。
FSR抵抗値 = ((電源V - 取得電圧V) * 使用抵抗値) / 取得電圧
なので
FSR抵抗値 = ((3.3 - 取得電圧V) * 10,000Ω / 取得電圧
で算出した 抵抗値vs重さのグラフ
メーカ資料の右側のグラフと符号している、よかった。
次は、これに回帰式をたてることにする。(続)
閑話休題: この作業時にchrome cast してたのは、こちら。
反する万の理由があろうと、私の希望にはひとつの理由さえあればいい。
勇気をもらえる。
Lady Gaga - Million Reasons (Live At Royal Variety Performance)
卒業研究奇 死闘編 変換地獄
前回まででとにかくセンサーから値をとりだせた。
えっとこの値はなんだろう。ということで。(大変がんばって検索して)調べたところ。
spiデバイスからの応答、(だいたい)10bitでかえってくるそうです。つまり0-1023の間です。
でその値は電圧に読み替えるには、ということでgoogle呪文「fsr 電圧」で召還された偉人のページを拝見すると。
サンプルコードにこうある。
void setup(){
Serial.begin(9600); // シリアル通信速度
}
void loop(){
// 変数の宣言
double Vo, Rf, fg;
int ain = analogRead(1);
// アナログ入力値から出力電圧を計算
Vo = ain * 5.0 / 1024;
// 出力電圧からFRSの抵抗値を計算
Rf = R1*Vo / (5.0 - Vo);
// FRSの抵抗値から圧力センサの荷重を計算
fg = 880.79/Rf + 47.96;
// 荷重データをシリアル通信で送る
Serial.println(fg);
delay(1000);
}
つまり、アナログ値0-1023 → ボルト範囲 0-5.0 にマッピングするばよいということになる。
上記は Arduino なので使用電圧は5v 、こっちはRaspberry Pi なので 3.3v
なので FSRからの電圧 = 取り出したデータ /1024 * 3.3 ということ。
で、この電圧から重さを出すには まず 抵抗値を算出 して、そこから計算式で荷重をだせばいいのですね。
fg = 880.79/Rf + 47.96;
これは、どこから? どこからかの引用のようですね。
ArduinoとFSRで重さを調べる(1) - フィジカル・コンピューティング
ArduinoとFSRで重さを調べる(2) - フィジカル・コンピューティング
実際のモノの重さと値の相関から回帰式を捻出している。
なぜだろう。公式の資料にあたろう。
データシートをみるとこうある。
センサーは、物理的にいく層のレイヤーになっていて、もともと電気的に抵抗がかかっている状態。でも、上から力がかかると、レイヤーの接触面が増えて電気の通りがよくなる(=抵抗が減る)。その電気の通りの程度→電圧の変化によって間接的に力を検知するのがこのセンサーらしい。(いまさら理解。。)
で、電圧の変化と力の関係は以下とのこと。
抵抗が減少(=電圧が増える) ということは力が強くかかっているという関係を表したのが左のグラフ。電圧が増えることと力の関係を表したのが右側のグラフ、構成する回路にはさむ抵抗の値によって関係式が変わってくるようです。私の場合は10Kオームの抵抗なので紫の線ですね。でこの線の関数式はどこに。
‥‥
‥‥
どこにもない。インテグレーションガイドにもない。グラフでしか提供されいない。
もしかしてイメージですか、こんなイメージでございます、ということなのか。
「お客様の個人的な意見です、適切な運動と食事管理もおこなった結果です」
と、そういうことなのか orz
そうか。だから、さっきの偉人は回帰式を専用のソフトで捻出していたのですね。
もう、これ以上自分の環境と同一の偉人は召還できなさそうなので、変換式はみずからなんとかしなければならなくなりました。(続)
閑話休題: このときのchromecast はこれ、文句なし。
卒業研究奇 死闘編 工作迷路
Raspberry Pi側の設定が終わったので、残すは工作のみ。
それはもう、ここをみてこのまま作ればいいわけで。
‥‥ん。A/DコンバーターがMCP3002 で、私が買ったキットに付属してるのはMCP3008 。
でデータシートをみにいくと。3002が
で、3008が
それぞれ何を意味してるのかさっぱり。
まあ、VDD/VREF が二つにわかれーのVSSが消滅して、あらたにAGNDとDGNDが出現したことと、チャンネルが増えたということが違うなと。
で、(すごくがんばって)調べたところ、VDD/VREFは電源的な意味あいと考えてよし、でVSS、GNDはアースなので、VSSでつながってた線は、AGND DGNDに読み替えればよしという、「あくまで個人の感想です」レベルで工作を始める。
ラズパイ側のピン配列を上記で確認しつつ。
#!/usr/bin/env python import spidev import time import subprocess #spiデバイスオープン spi = spidev.SpiDev() spi.open(0, 0) try: while True: res = spi.xfer2([0x68, 0x00]) value = (res[0] * 256 + res[1]) & 0x3ff print value time.sleep(1) #sleep 1sec except KeyboardInterrupt: spi.close()
意味合いとしては、デバイス(チャンネル0)を呼び出して、かえってきたデータを読んで一秒ごとに画面表示する、スクリプトですよね。
センサーを指でいくらつまもうが、0,0,0,0 表示。
配線が悪かったかな、もう一回見直し。 0,0,0,0
さっきの読み替えが悪かったかな調べなおし。0,0,0,
ワイヤーのコネクタとセンサーのピン(平たい)の適合性がわるからかな。ボードに直指し。0,0,0
‥‥。
はい、動きませんでした。
こういうまったく、未知のとこでうまくいかないとどうしようもない。
いったん戻るベースキャンプないわけです。
僕にとって電子工作で、いったん退却するところはほぼふもとなわけです。
そんなときオトナは、悲しまず、広大なネットから新たな偉人を召還します。
見つかったのは海外の偉人。
Using a Force Sensitive Resistor with a Raspberry Pi
MCPも3008で配線図もばっちり、Pythonスクリプトも githubで公開している。
spidev ではなく、GPIOライブラリを使っているので、コードもちょっと細かくなる。
見たところ、0.5秒ごとに、センサー値を読んで、変化があれば値(0-1023 の間) で表示する。
みたいなスクリプトで、やっていること自体はそんなかわらなさそう。
でほぼそのままのスクリプトをファイルにして、sudo python (スクリプト名).py で実行、センサーをつまむと、実際123,358‥‥、とか値が画面に表示される。おお。
「やった、もうできた。完成だ」
いや、まったく完成してないけどね。(続)
閑話休題: このときのchromecastしてたのは、これ。めちゃくちゃかっこいい。
卒業研究奇 続暖機編
アナログ機器のコントロールには、Pythonでそれ用のライブラリ spi を使用する必要があるらしい。
ということで、その準備をする。以下もテックシェアストアからの引用です。
sudo apt-get update
sudo apt-get upgrade
用心のためのRaspberry Pi の更新とアップグレード。
次にpythonの開発バージョンをいれとく
sudo apt-get install python-dev
git 経由でライブラリ入れるので、git もいれとく
sudo apt-get install git
で、spi ライブラリをgit で入手する。
git clone http://github.com/doceme/py-spidev.git/
cd py-spidev
sudo do python setup.py install
で spi ライブラリのインストール完了。python を起動し、インタラクティブモードで
import spidev
でエラーがでなければインストール成功。
で、import spidev でエラーなし、成功。
もちろんspidevライブラリについてクラスとか関数とかグローバル変数とかそういったことをまじめに調べるなどということは、淡きこと水の如しを信条としているため一切しない。(続)
卒業研究奇 暖機編
数年ぶりのLinuxであるし、そもそもハードウェアコントロールや電子工作なんて初心者なので、購入したテックシェアストアのスターターキットに付属のチュートリアルにそって、とにかく動くものを作ることにする。(以下、テックシェアストアから引用)
まず、そもそもこの配線板というか、ブレッドボードすら知らないわけで。
サイドがずらっとつながってて、真ん中は横がセグメントごとにつながってると。
これにジャンパワイヤーとよばれる細い線をつなぐんですね。
で、LEDをRaspberry Pi からの命令で点灯するための、これが回路図。
はい、もうすでにわかりません。
とはいえ、というところで。もうほんといっぱいネットを調べました。
左の箱がRaspberry Pi のピンたちをあらわしていて5v とか 3V3(3.3V)は電源らしくっていわゆる+の電極のイメージ、GNDはアースとかグラウンドとかいっていわゆる-のこと。その他 GPIOなんたらは、コントロールするためのI/Oの口みたいなもの。で上記は、3.3Vの電圧でLEDを点灯させて、39番のアースにつなぐという意味、でLEDは抵抗がないので、そのまま流すと電流流れすぎるいわゆるショートしてしまうので、510オームの抵抗をいれている。
で、これは3.3Vにそのままつないでるので、Raspberry Pi に電源いれるとそのままLEDがつく。で、実際やってみたら点いた。もうこれ以上は深く考えない。
次にPythonから、LEDの点灯、消灯を行う。
こんどは、29番PINであるGPIO5 からLEDにつなぐ。で sudo pythonで起動。
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
LED1 = 5
GPIO.setup(LED1, GPIO.OUT)
GPIO.setup(LED1.GPIO.HIGH)
で、LED点灯
GPIO.output(LED1, GPIO.LOW)
で消灯。
GPIO.cleanup()
exit()
で、GPIOの接続クリアして、終了。
なるほど、点いたし消えた。
で、当然、もうこれ以上GPIOライブラリをマニュアルをみるとか深入りはしない。
ということで、次はアナログ機器との接続を試すことにする。(続)
卒業研究奇 設定編
ということでまずは、Raspberry Pi のセットアップ。やることは。
1. OSのインストール
2. ネットワーク設定
3. もろもろ環境設定
でそのあとにやっとセンサーうんぬんとなる。
1.OSのインストール
Raspberry Piをモニターとキーボードなしで導入する(その1)SSHでのログインまで | 株式会社インデペンデンスシステムズ横浜
我が家は、ノートPC環境で、キーボードやモニタがないので、ネットワーク経由でのインストールが条件なので、上記を参考にインストール。
OSは「NOOBS」、「Raspbian」などのLinux がインストール可能とのこと、深い意味もなく「Raspbian」を選択(ちなみ、もともとLinuxディストリビューションにはDebianというのがあってそれにちなんでRaspberry Pi用に開発されたものだと思うので、なにかその別の意味合いがある名前ではないと略)した。
ということで、Raspbianのディスクイメージをダウンロード、SDカードに焼いて、Raspberry Piにさして、192.168.0ネットワークを前提に、ノートPC側のIPをあわせて、Raspberry Piを探索、発見できたらログイン、なんと Raspberry pi 3には無線LANがついてるので、以下ページを参考に、我が家の設定にあわせる。
2. ネットワーク設定
Raspberry Pi の初期設定 | OpenRTM-aist
これで、ノートPCから、無線で Raspberry Pi に接続できるようになった。
3. もろもろ環境設定
で、もろもろ設定は、いらないサービスとめたり、aptでパッケージ更新したり、gitで更新したり。
とくにもろもろやりはしたが、ネット情報そのままで特につっかかるトコロなし。
ダルい感しかなく、嵐の前のシヅケサ。(続)