2008年08月30日 [ColdFire] ColdFire×P2P地震情報(3) サンプリングを等間隔に行おう
_ [ColdFire] ColdFire×P2P地震情報(3) サンプリングを等間隔に行おう
Interface 9月号付録基板を使い,P2P地震情報のサービスを作ってしまう勝手な企画です.過去の記事は,タイトルのColdFireカテゴリからどうぞ.
前回のおさらい
- 加速度センサの値0〜4095と,加速度-2022.62 Gal〜+2022.62 Gal(重力加速度-2.06G〜+2.06G)が対応しています.
- 地震計として使うためには,「ズレ」「ノイズ」「サンプリング間隔」の3点を考える必要があるようです.
番外編: アナログとデジタル
アナログデータをデジタルデータに変換する時に問題となるのは,アナログデータは常に変化していて,その変化は連続的であるという点です.一方のデジタルデータは,変化の時間間隔と変化の単位が定められており,離散的です.
時計で言うと,連続秒針タイプのアナログ時計はズズズーッと滑らかに時を刻みますが,デジタル時計は秒単位で刻むことしか出来ません.アナログのモノをデジタルに変換する時には,どうしても情報の欠落が生じます.
サンプリングってなんだっけ?
今回は,課題のうち「サンプリング間隔」を取り上げます.サンプリングは,アナログデータをデジタルデータに変換する時に必要となるものです.どんなものかをざっくり見ておきます.
音声,電圧などのアナログデータ(波形)がある時に,一定の時間間隔でデータを読み取ることを『標本化(サンプリング)』と言います.1秒あたりの読み取り回数をサンプリング周波数(Hz)で表します.
それだけです.サンプリングは一定間隔で行うものですから,サンプリングを等間隔で行うのは当然なわけです.
ただし,デジタルデータに変換するには『量子化』も必要です.その時のデータがどの程度なのかを離散的な(とびとびの)数値で表します.その細かさを量子化ビット数で表します.8bitだと256段階の値で表すことが出来るわけです.
等間隔に行うということは,時間の概念を使うということ
サンプリングを等間隔に行うということは,一定の時間間隔で行うということであって,すなわち時間の概念を取り入れなければなりません.仮にサンプリング周波数が10Hzであるならば,1秒に10回,100ミリ秒に1回の計測を行う必要があるわけです.
SilentCのタイマ
というわけで,時間の概念を取り入れましょう.SilentCの仕様を見ると,タイマが用意されています(SilentSystemの(PDF) OS-1プログラミングマニュアルを参照).マニュアルではタイマーと表記されていますが,ここではタイマと表します.
SilentCのタイマでは,作成,更新(上書き),取得,削除の4つが可能です.カウントが0になった時に関数を呼べるような記述がありますが,うまく行かなかったのでパスします.
まず思いつくのは,サンプリング間隔(10Hzであれば100ms)のタイマを作って,カウントが0の時にデータの取得・タイマの上書き動作を行う方法です.
main(){ char t1; int cnt; t1=CreateTimer(0,10,0);cnt=0; for(;;){ if(GetTimerCount(t1)==0){ CreateTimer(t1,10,0);cnt++; if(cnt%5==0){PrNum(cnt);PrStr("\r\n");} if(cnt==600)break; } SystemSleep(); } PrStr("Complete.\r\n"); CreateTimer(t1,0,0); }
100 msのタイマを600回,つまり60 sのあいだ実行します.WireSharkでパケットを見ると,実行時間は60.01 sとなかなか正確です.しかし,これでは問題があります.
- ループ内に様々な処理を加えると,「タイマカウンタが0になってから,0かどうか調べて更新するまでのディレイ」が起こり,それが蓄積する可能性があります.
- 1ループに掛かる処理時間がタイマの指定時間を上回っていれば,確実にズレます.
これらの問題を緩和しましょう.次のようなプログラムを用意します.引数は hz: サンプリング周波数,slp: スリープ時間(10 ms単位) です.ただし,hzは100の約数を指定します.
ctr(int hz, int slp){ char t1; int cr,nx; int i; i=0; hz=100/hz; nx=30000; t1=CreateTimer(0,30000,0); #stop 0 for(;;) { if(Getc(0)!=0)break; cr=GetTimerCount(t1); while(cr<=nx){ i++;PrNum(i);PrStr("\r\n"); nx-=hz; if(nx<0)nx+=30000; } if(cr==0)CreateTimer(t1,30000,0); if(slp==0){SystemSleep();}else{Sleep(slp);} } CreateTimer(t1,0,0); }
- タイマカウンタを30000(300 s)に設定することで,「タイマカウンタが0になってから,0かどうか調べて更新するまでのディレイ」の発生頻度を300 s/回に抑えています.
- その代わり,実行判定を「タイマカウンタが0かどうか」でなく「タイマカウンタが次の実行時間を過ぎているか」としています.
- 1回のタイマカウンタ取得で,複数回の実行を認めています.
- "タイマカウンタ取得間隔 > サンプリング間隔" となった場合にサンプリング回数を稼ぎ,「全体で見ればサンプリング周波数を保っている状態」に立て直します.
FILENAME::ctr(10,123) と呼び出してみると,サンプリング間隔こそ狂えどサンプリング回数は10 回/秒になっていることが分かります.
あまり良い方法ではないのは確かですが,この辺りで妥協します.
今回のまとめ
- タイマを使うことで,サンプリング回数を保つことがそれなりにできました.
参考
2008年08月27日 [ColdFire] ColdFire×P2P地震情報(2) 地震計としてのColdFire基板
_ [ColdFire] ColdFire×P2P地震情報(2) 地震計としてのColdFire基板
Interface 9月号付録基板を使い,P2P地震情報のサービスを作ってしまう(かもしれない)勝手な企画です.過去の記事は,タイトルのColdFireカテゴリからどうぞ.
前回のおさらい
- 『ガル(gal)』は加速度の単位で,センチメートル毎秒毎秒(cm/s^2)を指します.
- 気象庁の震度は,3軸加速度センサの値から計算した計測震度をもとにしています.
- ColdFire基板では計測震度の計算は困難であることから,バンドパスフィルタを掛けた最大加速度『5HzPGA』っぽいものの計算を目指すことにしました.
ColdFire基板の加速度センサ "MMA7360L"
ColdFire基板には,3軸加速度センサとしてMMA7360Lが実装されています.感度として ±1.5 g,±6 gの2種類が選択可能で,1.65 Vを0 gとし,±1.5 gモードの時は800 mV/g(1 gあたり800 mV)の直線変化を示すようです.
ただし,これらはTypicalの値で,0 gの電圧は1.485 V〜1.815 Vの間,1 gあたりの感度は740 mV/g〜860 mV/gの範囲で変動することに注意しましょう.
1 G = 9.80665 m/s^2 = 980.665 cm/s^2 = 980.665 Gal であるから, 1.5 G = 1470.9975 Gal 6 G = 5883.99 Gal
前回紹介したガル換算ではこのようになります.岩手・宮城内陸地震で4022 Gal(3成分合成)が観測されたことを考えると「±1.5 gモードじゃ足りないかな」と思いますが,このような値を示すことは極めて稀です.中〜小規模の揺れに対する精度を確保するためにも,±1.5 gモードが適切と言えるでしょう.
なお,観測点の位置関係も考えると正確な比較は出来ませんが,新潟県中越地震の余震で2515 Gal(3成分合成),阪神淡路大震災で818 Gal(南北成分)が観測されています.
ColdFire基板のColdFire "MCF52233"
ColdFire基板には,ColdFireとして(?)MCF52233が実装されています.
データシートを見る限り,12bit A/Dコンバータを8チャネル持っているようです.入力電圧は0 V〜3.6 V,応答速度は最小1.125 μsとなっています.
例えば,入力電圧を0.85 V〜2.45 Vと設定すれば,±1.5 gモードに設定した状態では-1 g〜+1 gまでの区間が4096段階で読み取れる計算になります.
ColdFire基板のA/Dコンバータはどう設定されているか
Interface 9月号の付録基板 "CQ-FRK-MCF52233" では,A/Dコンバータがどのように設定されているでしょうか.
回路図や仕様はあまり読めない人なのでテキトーな解釈ですが,入力電圧の設定にはV_RL(V_REFL)とV_RH(V_REFH)が関係していて,V_RLはグランドと接続,V_RHは入力電源と接続されているようです.
つまり,入力電圧は0.0 V〜3.3 Vに設定され,±1.5 gモードにおける加速度の範囲と出力値の関係はたぶん次のようになります.
電圧 (V) | 加速度 (G) | 加速度 (Gal) | 12bit 出力値 |
0.00 | -2.06 | -2022.62 | 0 |
0.05 | -2.00 | -1961.33 | 62 |
0.45 | -1.50 | -1471.00 | 558 |
0.85 | -1.00 | -0980.67 | 1054 |
1.25 | -0.50 | -0490.33 | 1551 |
1.65 | *0.00 | +0000.00 | 2047 |
2.05 | +0.50 | +0490.33 | 2543 |
2.45 | +1.00 | +0980.67 | 3040 |
2.85 | +1.50 | +1471.00 | 3536 |
3.25 | +2.00 | +1961.33 | 4032 |
3.30 | +2.06 | +2022.62 | 4095 |
もちろん,±1.5g モードですから,+2.06 Gなんて値は出ないでしょうが.
SilentCにおける,加速度センサのデータ
さて,SilentCでは加速度センサの値をどう扱っているのでしょうか.次のようなプログラムで実験してみましょう.
main() { InitAd(0x70); #stop 0 for(;;) { if(Getc(0)!=0)break; PrStr("x:");PrNum(GetAd(4)); PrStr(", y:");PrNum(GetAd(5)); PrStr(", z:");PrNum(GetAd(6)); PrStr("\r\n");SystemSleep(); } }
初期化して,おまじないをかけて,3軸の値をひたすら出力し続けます.何かキーを押すと止まります.
なお,数サンプルごとにまとめて受信・表示されますが,これはNagleアルゴリズムと遅延ACKによる仕様です.
x:2006, y:2089, z:2816 x:2001, y:2114, z:2818 x:1992, y:2078, z:2807 x:1996, y:2088, z:2819 x:1990, y:2079, z:2811 (ここでキー入力) OK
ネギ以上に思いっきり振ると0〜4086あたりで変動することや,それぞれの軸に対して重力を掛けるとだいたい表の通りに変動することから,± 1.5gモードでA/Dコンバータを通った値がそのまま入るようです.±1.5 gモードなのに±2 g近く出ていることになりますが,「±1.5 gまでは正確に測定するけど,それ以上は知らないよ」という性質のものとしておきましょう.
まっすぐ置いた状態では,z軸に1 G,他は0 Gですから, "x:2047, y:2047, z:3040" となるのが理想です.しかし,「加速度センサ・A/Dコンバータの仕様の範囲内で」それぞれズレていますし,揺らぎ(ノイズ)もあるようです.
とにかくGal表示をやってみたい!
A/Dコンバータを通った値をそのまま表示しても面白くないので,簡単なコードでGalの近似値を出力してみましょう.
main() { long i; InitAd(0x70); #stop 0 for(;;) { if(Getc(0)!=0)break; // "PrNum((GetAd(4)-2048)*80/81);" が動かない為,途中経過を入れる PrStr("x:"); i=(GetAd(4)-2048)*80;PrNum(i/81); PrStr(" Gal, y:");i=(GetAd(5)-2048)*80;PrNum(i/81); PrStr(" Gal, z:");i=(GetAd(6)-2048)*80;PrNum(i/81); PrStr(" Gal\r\n");SystemSleep(); } }
x:-31 Gal, y:47 Gal, z:750 Gal x:-46 Gal, y:58 Gal, z:742 Gal x:-50 Gal, y:60 Gal, z:745 Gal x:-47 Gal, y:54 Gal, z:749 Gal x:-36 Gal, y:49 Gal, z:740 Gal (ここでキー入力) OK
やはりズレとノイズが気になります.
"地震計" としてのColdFire基板
さて,A/Dコンバータの値を読み取り,Galに換算することが出来ました.しかし,これだけでは問題があります.
- 理想の値とズレが生じています.
- 加速度センサによる0 gの電圧差は約±200 Galの差として現れることがあります.
- 加速度センサによる1 gあたりの感度差は約±75 Galの差として現れることがあります.
- ノイズがあります.
- サンプリングをなるべく等間隔に行う必要があります.
- ネットワークとの通信やSilentCの処理などにより,実行時間が変動することを考慮しなくてはなりません.
次回以降,この辺りを考えていきます.
今回のまとめ
- 加速度センサの値0〜4095と,加速度-2022.62 Gal〜+2022.62 Gal(重力加速度-2.06 G〜+2.06 G)が対応しています.SilentCでも同じです.
- 地震計として使うためには,「ズレ」「ノイズ」「サンプリング間隔」の3点を考える必要があるようです.
参考
- http://www.freescale.co.jp/pdf/MMA7360Lr1.pdf
- http://www.k-net.bosai.go.jp/k-net/topics/Iwatemiyaginairiku_080614/IWTH25_NIED.pdf
- http://www.jma.go.jp/jma/press/0412/24a/kyoushinhakei.pdf
- http://www.bousai.go.jp/1info/kyoukun/hanshin_awaji/earthquake/index.html
- http://www.freescale.com/files/32bit/doc/data_sheet/MCF52235DS.pdf
- http://www.cqpub.co.jp/interface/download/2008/09/kairozu.pdf
2008年08月26日 [ColdFire] ColdFire×P2P地震情報(1) 震度計としての加速度センサ
_ [ColdFire] ColdFire×P2P地震情報(1) 震度計としての加速度センサ
はじめに
Interface 9月号付録 "ColdFire基板" を使って,P2P地震情報のサービスを作ってしまおう! という,勝手な企画です.楽にやりたいので,SilentCインタプリタで頑張ります.目標は次の通り.
- 簡易震度計ネットワーククライアント
- 加速度センサの値を適切に処理し,集計サーバに送信する
- ゲートウェイ方式のP2P地震情報クライアント
- Interface 10月号にあるような,ゲートウェイ方式(クライアント-サーバ型)のP2P地震情報クライアントを制作
- ハイブリッドP2P方式のP2P地震情報クライアント(ピア)
- たぶん無理だけど,別ネットワークでもいいからP2P方式のクライアントを制作
「クライアントを作ってどこに表示するの?」というのは,また別の話です.というわけで,早速始めましょう.
"震度計" としての加速度センサ
『震度』を知らない人はいないでしょう.緊急地震速報でも,地震情報でも,当たり前のように見かけます.この震度,正確には震度階級は「0〜4,5弱・5強,6弱・6強,7」の10段階で,『計測震度』から換算されています.1.5だったら震度2,という具合です.
突然ですが,この計測震度はどうやって換算されているでしょうか.そう,ここで加速度センサが登場します.計測震度の計算に,3軸の加速度センサが使われているのです.つまり,3軸加速度センサが実装されているColdFire基板は,震度を計算可能なポテンシャルを持っています.ただし,加速度センサの値をそのまま使うだけでは,震度を計算することはできません.
『ガル(gal)』という単位,「地震で○○ガルを記録した」「原発の耐震基準は○○ガル」といった形で名前だけ知っているという方も多いのではないでしょうか.これは加速度の単位で,センチメートル毎秒毎秒(cm/s^2)を指します.
しかし,加速度は必ずしも被害や体感と直結した値ではないことが分かっています.そこで,地震波の周期などを考慮し,加速度と速度の中間を求めるような式を用いているのが,気象庁の計測震度です.
番外編: 昔の震度、海外の震度
昔の『震度』は,人間の体感や被害の様子に応じて決められていました.また,その震度に相当する最大加速度が示されていました.家庭用震度計として有名な『グラグラフ(GraGraph)』は,この最大加速度によって震度を算出しているようです.
震度 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
加速度(gal) | 〜0.8 | 0.8〜2.5 | 2.5〜8 | 8〜25 | 25〜80 | 80〜250 | 250〜400 | 400〜 |
一方,海外では現在も『改正メルカリ震度階級』『MSK震度階級』などが使われていて,概ね体感や周辺の様子に基づき決定されています.目安となる最大加速度を示すところもありますが,ここでは省きます.
ColdFire基板で "計測震度" は非現実的,『5HzPGA』を使う
では,ColdFire基板で計測震度を算出… したいところですが,計測震度の計算にはフーリエ変換,フィルタ処理などが含まれており,これを実用的な速度で行うのはかなり難しそうです(それ以前にメモリが足りないかもしれません).
でも心配はいりません.『5HzPGA』というものがあります.これは,0.1Hz〜5Hzまでのバンドパスフィルタを掛けた最大加速度のようで,純粋な最大加速度と比べて震度との対応が良いようです.今回は,この5HzPGA『のようなもの』を目指すことにします.
参考
- http://www.seisvol.kishou.go.jp/eq/kyoshin/index.htm
- http://www.k-net.bosai.go.jp/k-net/topics/chuetsuoki20070716/pgav5v20070716.html
- http://www.sdr.co.jp/papers/strong_motion_index.pdf
- http://www.nilim.go.jp/lab/bcg/siryou/tnn/tnn0357pdf/ks0357009.pdf
- http://www.geocities.co.jp/Technopolis-Mars/8897/FIG/200/shindotb.htm
- http://www.uwiseismic.com/Downloads/Eq_mercalli_scale.pdf
- http://www.mri-jma.go.jp/Publish/Papers/DATA/VOL_20/20_275.pdf
- http://www.store-mix.com/ko-bai/product.php?pid=1103077
2008年08月21日 [レビュー] VMware Player, VMware Server, VirtualBox, VirtualPC
_ [レビュー] VMware Player, VMware Server, VirtualBox, VirtualPC
バーチャルマシン比較。あくまで使った範囲の主観に基づくものですから、このデータを参考にしようと考えてはいけません。
まとめ
- 速度: VMware Player > VirtualBox >> VMware Server >>> VirtualPC
- NASにディスクイメージを置く場合はVirtualBox(キャッシュか?)
- 安定度: VMware Server ≒ VirtualPC >= VMware Player >> VirtualBox
- Windows系はVirtualPCが良い、Linux系はVirtualBoxでもなんとか。
- 設定の簡単さ: VirtualPC > VirtualBox > VMware Server >> VMware Player
- VMware Playerは「新たな環境構築」という点でダメ
- とにかく手軽にしたいなら VirtualPC
- 設定は適当にこなせるからサクサク動かしたいなら VMware Player
- Linux系をサクサク動かすなら VirtualBox
- ガッツリ(?) or リモート操作でやるなら VMware Server
VMware Player
- 速い。
- 仮想環境を新しく構築するのは面倒。
VMware Server
- 遅め。
- 設定項目多数。間違うとメモリが食い尽くされてとんでもないことに…
- リモート操作(VMware Server Console)するなら選択の余地なし。
VirtualBox
- 速め。
- 設定項目多数。
- ディスク操作に対しキャッシュを持っているらしく、NASにディスクイメージを置く場合は他より速い。
- 不安定。Vine Linuxとかはすんなり入るよ!
VirtualPC
- 遅い。いや、本当に遅い。ディスクアクセスが遅いのか?
- 設定項目少なめ。
- Windows系はそこそこ動くはず。
- 簡単さを取ってもいいけど、それより遅い。