2009年05月25日 [ColdFire] ColdFire×P2P地震情報(B) 独自フィルタ vs SI値 (?)
_ [ColdFire] ColdFire×P2P地震情報(B) 独自フィルタ vs SI値 (?)
estimaさんからSI値の計算データと計算方法をいただいたので,どんなものかと,従来の方法とあわせて比べてみました.
比較方法
- 気象庁が公開する地震の観測データを用いる.
- 震度5弱〜7を観測した,7つの地震・143のデータ.
- サンプリング周波数は100 Hz,ほぼすべて0.001ガル単位での記録.
- 従来の方法(独自フィルタ)による値とSI値を計算する.
- 独自フィルタ: 100サンプル移動平均を基準点(オフセット)とし,15サンプル移動平均をデータとする.
- フィルタ特性は "(5) ノイズを除去する" に記載(20 Hz時のものだが,100 Hz時とほぼ同等のはず).
- SI値: "<PDF> インテリジェント地震センサの開発" に記載されている計算法をもとにした数値積分計算を行う.
- ただし,後述する理由により,100サンプル移動平均を基準点(オフセット)とする.
- 固有周期 T は,0.1から2.5までの区間を0.1刻みで計算
- 独自フィルタ: 100サンプル移動平均を基準点(オフセット)とし,15サンプル移動平均をデータとする.
震度換算値は,それぞれ近似曲線(回帰曲線)の式を用いて算出することとします.
ゼロ点(オフセット)のズレによる,積分時の問題について
新潟県中越地震では,いくつかの観測点でゼロ点(オフセット)のズレのようなものが発生しており,加速度を積分して速度あるいはSI値を算出する際に,延々と速度・SI値が増えていくという問題が発生しました.
<PDF> 全観測データの計算結果(異常と思われるものに色付け)
そこで,独自フィルタで用いていた「100サンプル移動平均を基準点(オフセット)とする」方法を,SI値の計算にも適用することとしました.これにより,先述した問題は以下のように解決します.
比較結果
うーん,SI値がやや劣る結果になりました.
詳しく見ると,揺れの周期が長いと思われる十勝沖地震(本震・最大余震)での精度が悪く,相関係数(R^2)は,SI値(3方向)で0.35,独自(3方向)で0.64となりました.それを除くと,SI値が0.85,独自が0.93と良好ですが,SI値の相関が劣る状況は変わりません.
ColdFire基板の加速度センサデータは
いや,ColdFire基板の加速度センサデータなら,「平常時震度3」という状況を改善出来る方法として使えるかもしれない…!
…あれ,あれれ?
SI値を使うのはちょっと微妙かも.
参考
2009年04月12日 [ColdFire] ColdFire×P2P地震情報(12) 改めて,ノイズを見る: 乾電池 vs スイッチング電源
_ [ColdFire] ColdFire×P2P地震情報(12) 改めて,ノイズを見る: 乾電池 vs スイッチング電源
Interface 9月号付録基板を使い,P2P地震情報のサービスを作ってしまう勝手な企画です.過去の記事は,タイトルのColdFireカテゴリからどうぞ.
ColdFire基板を乾電池で動かす
前回掲載した24時間ぶんの加速度センサデータに含まれるノイズについて,スイッチング電源が原因ではないか,という指摘がありました.こうした分野には詳しくないのですが,小型で効率が良い反面,スイッチングによるノイズが発生してしまう,ということのようです.
そこで,乾電池を使ってみました.
- マンガン乾電池(単三)を2本,直列で繋ぐ
- Interface 2008年9月号や回路図を参考に,48番(+3.3V)に乾電池のプラス,49番(GND)に乾電池のマイナスを接続する
マンガン乾電池 1.5 V × 2 = 3.0 V (くらい) になります.動作電圧は,ColdFire自体は 3.0 V〜3.6 V,加速度センサが 2.2 V〜3.6 Vらしいので,ギリギリといったところです.ちなみに,各デバイスが耐えうる電圧は,ColdFire自体が -0.3 V〜4.0 V,加速度センサが -0.3 V〜3.6 Vです.この範囲から外れた電圧を与えると壊れる恐れがあるので,注意が必要です.
なお,eneloopなどの充電池はほとんどが 1.2 Vくらい なので,2本直列しても 2.4 Vくらい にしかなりません.3本直列でギリギリです.
A/Dコンバータのエラッタ
こちらは実験した後に思い出しましたが,A/Dコンバータにはエラッタがあります.MCF52235 Device Errataに記載されています.
5 ADC Might Give Erroneous Results if the ADC
Reference Voltage (VREFH) is Below 3.1 V
A/Dコンバータのリファレンス電圧(High)に3.1 V以下の電圧を与えると,100 mVを下回るような入力に0を返したり,正しい値を返す前に誤った値を返したりといったことが起きるかもしれない,というものです.
今度の実験は,eneloop×3(3.6 V)でしょうかね.
結果
すぐ電圧が下がってしまうようで,5分ちょっとしかデータが取れませんでした(リセットされ,電源は入るがEthernetが動作しない).ほとんどアテになりませんが,ひとまずスペクトラムだけ載せておきます.
FFTスペクトラム画像(PNG, 756KB, 1680x815)
どういうことなの… 十分なデータとは言えないので,後日もう少しじっくりと調べてみます.
参考
2009年03月13日 [ColdFire] ColdFire×P2P地震情報(11) 改めて,ノイズを見る: 24時間(1)
_ [ColdFire] ColdFire×P2P地震情報(11) 改めて,ノイズを見る: 24時間(1)
Interface 9月号付録基板を使い,P2P地震情報のサービスを作ってしまう勝手な企画です.過去の記事は,タイトルのColdFireカテゴリからどうぞ.
24時間サンプリングをやってみました
あまり時間がないので,FFTスペクトラムの画像だけ放り投げ.
FFTスペクトラム画像(PNG, 854KB, 1564x840)
測定データ
- 2009/03/11 21:00 〜 2009/03/12 21:00
- ColdFire基板 加速度センサ 全軸データ(画像はX軸のみ)
- 293.3Hzサンプリング
測定環境
- 天気は晴れ,午後には基板に日差しが当たることも
- 周辺温度が上昇しやすい.
- 温度は測定せず.過去に温度計を使っていた経験からすると,今回は最低12度〜最高22度ぐらい
- 基板 / 輪ゴム / 床 (基板 on 輪ゴム on 床)
- ACアダプタは LTE 101U-A320,交流周波数は60Hz(西日本)
- 電源ケーブル両端にフェライトコアを1つずつ取り付け
送信部
- telnet接続→ InitAd(0x70) → 下記プログラム(U_Fwd::main)
- 送信されるデータはバイナリ,16進数表記で次のようになる.
- XX XX YY YY ZZ ZZ 0D 0A
- XX XX 〜 ZZ ZZ は各軸データの2バイト整数値
- 0D 0A はCRLF(改行)を示すが,特に意味はない
- ビッグエンディアンであるから,コンピュータ側の処理に注意すること.
- XX XX YY YY ZZ ZZ 0D 0A
main() { char soc,*ctr;ctr=0x40190000;int *dat;dat=0x40190012; int *sd=MemoryAlloc(8); soc=CreateSocket(0);if(soc<0){PrStr("S!");return;} Bind(soc,6909,0);sd[3]=3338;PrStr("MARIO START!\r\n"); for(;;) { *ctr=32; sd[0]=dat[4]>>3;sd[1]=dat[5]>>3;sd[2]=dat[6]>>3; SendTo(soc,<IP Address>,<Port Number>,sd,8); SystemSleep(); } PrStr("GAME OVER\r\n"); CloseSocket(soc); }
解析部
- いったんリトルエンディアンに変換し,ファイル保存
- 各軸2バイト,計6バイトのデータと,1日の経過秒数を示す4バイト整数値をあわせて記録.
- AudacityでRawデータとして読み込む.
- Signed 16 bit PCM, リトルエンディアン, 5 チャンネル, 293 Hz
- 経過秒数を示す2チャンネル(4バイト)は削除.
- FFT 4096でスペクトラム表示.
2009年03月10日 [ColdFire] SystemRegistryでAuto=1にしてしまったときの対処法
_ [ColdFire] SystemRegistryでAuto=1にしてしまったときの対処法
- コンピュータのNICを「10Mbps 半二重」設定にして直結する.
とにかく,10Mbps 半二重に固定出来ればリンクします.BUFFALOのBBR-4HG/4MGやWHR-G54SのWANポートとかでも.
以下,対処法に至るまで
PC-98の「ピポッ」も実現すれば,楽しいだろう… などと妄想を膨らませつつ.SilentC_RegistryでAutorun=1にしようとして,何を思ったか,SystemRegistryでAuto=1に.あれ,リンクしないな? うわ,これ,SystemRegistryじゃん……… 涙目.
そのとき,ルータのランプがオレンジ(10Mbps)だったことを思い出し,涙目のままNICを設定.まさか,こんなことで繋がるわk …ランプ点いた!
古い話ですが,忘れないようにメモ.たかがColdFire基板,されどColdFire基板.あのときの絶望感はトラウマです.今は,Autorunで毎回元気に「ピポッ」と鳴ってくれます.
2009年02月10日 [PC][解析] WHR-G54Sルータ内にマジなサーバを立てるとき
_ [PC][解析] WHR-G54Sルータ内にマジなサーバを立てるとき
注意事項
- あやふやな知識ですから,鵜呑みにするのは推奨出来ません.
- ツッコミ歓迎.
結論(やるべきこと)
- ルータのNATは最低限に留める.
- NATしたポートには,「接続を受け入れる」「接続を拒否する」いずれかの応答を必ず行う.
- ファイアウォールのステルス機能によって「無応答」になることは避ける.
- クライアントに切断処理をさせる.
- 接続数が増えたと思ったら,ポートを閉じてしまう.
- Webサーバなら,同時接続数を制限したり,Keep-alive timeoutを延ばしたりする.
- ただし期待薄.
はじめに
P2P地震情報サーバを運営していますが,その追加機能であるPRCP情報共有プラグインの設計が大変悪く,結構本気で接続を仕掛けてきます.そのために,メンテナンス明けにはアクセスが集中し,ルータには決まって次のようなメッセージが表示され,ブラウズが大変遅く感じられるようになります.
ip_conntrack: table full, dropping packet.
ぐぐってみれば,おおよそNATセッションテーブルがいっぱいで,これ以上セッションを張れないということは分かります.でも,それでは納得がいきません.なんでそんなにいっぱいになるの?
調べてみました.
Q. 最大接続数を50に制限しているのに,いっぱいだなんて!
TCPの接続・切断の流れ(状態遷移図)がヒントになる.主なポイントは,次の2点.
- 「接続をしようとしている」コネクション (SYN-RECEIVED)
- ルータ内にあるサーバから切断処理を行い,「迷子のパケットを待つ」状態に移行したコネクション (TIME-WAIT)
まだ確立していなかったり,終わったかのように思えたりするコネクションだけど,こうしたコネクションもNATセッションとして管理されている.ルータは可能な限りTCPを理解し,TCPの規約・制約に沿った動作を行うようになっているのである.
だから,最大接続数が50であっても,こうしたセッションによってセッションテーブルはいっぱいになりうる.
Q. SYN-RECEIVEDってなに?
接続要求を受信した状態のこと.
例えば,TCP ポート2000〜2009をサーバに転送するよう,ルータを設定したとしよう.ただし,この10個のポートすべてをいつも使用しているわけではない.サーバのファイアウォールでは,2000〜2002の3つのポートは通信のために接続を許可しているが,2003〜2009はブロックしている.また,安全性を高めるために,接続要求を無視するステルスモードを使っている.
ここで,TCP 2003に接続要求が入ったとする.ルータは接続要求を検出して,NATセッションとしてテーブルに追加するだろう.しかし,サーバはステルスモードによってブロックしていて,何の応答も返さない.
| サーバ | ルータ | クライアント | | | | | | | | <= 接続要求 | | | [セッション発生] <= | | (SYN) | | | <= || | | | | [FWが無視]<= | || セッション | | | | | || 管理中 | [???] | | | || | (反応が | | | || | こないぞ?) | | | || (60秒後) | | | | | [セッション破棄] | [時間切れ] | | | | |
このとき,クライアントが接続要求をキャンセルするか,ルータ内部でSYN-RECEIVEDのタイムアウト(WHR-G54Sで60秒)を迎えるまで,NATセッションは残り続けてしまう.
Q. TIME-WAITってなに?
セッションを切断した後,ネットワークを漂流するパケットが消滅するまで一定時間待つ状態のこと.
あなたが,画像を多用するWebサイトをホストしているとしよう.今日多く見られる「行儀の悪いWebブラウザ」が,RFCの推奨を無視して8ものセッションを確立してしまった.Webサーバは,Keep-aliveタイムアウトになったので,8つのセッションを切断した.
ここで,8つのセッションはTIME-WAITと呼ばれる状態に移行する.TIME-WAITのタイムアウトはまちまちだが,WHR-G54Sなどでは,2分間NATセッションとしてテーブルに残り続けている.
| サーバ | ルータ | クライアント | | | | | | | | || | | | | 通信中 <=> | [セッション管理中] | <=> 通信中 | | | | || | | | | 切断処理 => | || | | | | | | => [切断処理検出] => | | | | | | || | => 切断受信 | | | | || | <= 切断OK | | | | <= [切断OK検出] <= | | | | 切断完了 <= | || | [CLOSED] | | | | || | | | [TIME-WAIT] | [TIME-WAIT ] | | | | | || | | | | | || | | | | | || (2分後) | | | [破 棄] | [セッション破棄] | | | | | |
ここで問題.「8セッションを確立する行儀の悪いブラウザと,1024のセッションテーブルを持ったルータがあります(サーバはルータ内にあります).このルータ内のサーバには,1時間当たり何個のブラウザと通信できるでしょうか?」
答え: 1時間あたりおよそ3700個.ある瞬間には, 1024 / 8 = 128 個のブラウザからのセッションを受け入れ可能である.それらのセッションは,通信を確立してから5秒で切断すると仮定すると,セッションとして残存する時間は 通信時間 5秒 + TIME-WAIT 2分 = 2分5秒 である.つまり,2分5秒あたり128個のブラウザが接続可能である.よって,単純計算で1時間あたりおよそ3700個.
余談になるが,「ブラウザの同時接続数を増やして高速化」などといった行為は,Webサーバ管理者にとって頭を抱える要因になることがお分かりいただけると思う.参考までに,RFC 2616では「2より多く(3以上)の同時接続はすべきでない(SHOULD NOT)」とされている.Internet ExplorerとFirefoxは標準でこれを守るようになっている.しかし,私が愛用するOperaは,4の同時接続をしてしまう行儀の悪いブラウザであった.
Q. SYN-RECEIVEDとか,TIME-WAITのほかに,どんな接続がNATセッションとして管理されるの?
TCPの状態で言えば,CLOSED以外すべて.
UDPだと,パケットがやり取りされて一定時間以内,という風になっている.
Q. NATセッションとして管理されないために(管理される時間を短くするために),どうすればいいの?
TCPセッションの状態をCLOSEDに持っていけばいい.そうすれば,NATセッションのテーブルから削除されるだろう.
Q. 具体的に,CLOSEDに持っていくにはどうすればいい?
1つは,クライアント(相手)に切断処理を行ってもらうこと.そうすれば,TIME-WAIT状態はクライアント側に発生し,サーバやルータにはセッションが残らずに済む.httpだとそうした制御は難しいが,独自プロトコルであれば,出来るだけクライアントが切断処理を行うように作っておこう.
2つめは,SYN-RECEIVEDのままルータに留まらせないこと.つまり, ファイアウォールのステルスモードによる無応答を避けることだ.例えば,Windows ファイアウォールでプログラム単位の設定を行っていると,プログラムが起動していない場合はステルスモードになってしまう.NAT設定は最低限に留めた上で,設定したポートについては責任を持って「受け入れる」か「閉じている」かの応答をしたほうがよい.
接続要求が大量にある場合は,いっそポートを閉じてしまう.丁寧にも,エラーを返してすぐに切断処理に入るような設計をしていると,そのぶんTIME-WAITが残ってしまうので,セッション数が増大してしまう.一方,ポートを閉じてしまえば,「閉じている(RST/ACK)」応答をしてセッションをすぐに破棄するので,セッション数を消費せずに済む.
| サーバ | ルータ | クライアント | | | | | | | | <= 接続要求 | | | <=[セッション発生]<= | | (SYN) | | <= | || | | | | (このポート | || | | | | 閉じてる…) | || | | | | | || | | | | 接続拒否 => | || | | | | (RST/ACK) | => [拒否を検出] => | | | | | || | => 拒否検出 | | | [セッション破棄] | | | | | | [CLOSED] | | | | |
さらに,バックログを活用する.プログラム内にソケット(セッション)を抱え込まず,処理できる量だけをバックログから引き取るよう,十分注意して設計しよう.処理しきれず,バックログがいっぱいになったときには,TCP/IPスタックが「拒否(RST/ACK)」応答をするようになっているから,セッション数はそれ以上消費されない.
Q. どれくらいで"table full"になるの?
実験では,約2000を超えたときに発生した.これは,BUFFALOのQ&A IPマスカレードテーブルのセッション数はいくつですか?(無線親機ルータモデル、BroadStation) に一致する.
Q. "table full"になったらどうなるの?
セッションテーブルに空きが出来るまで,新しい接続が出来ない.WHR-G54S特有の現象としては,処理能力がほぼ限界に近いらしく,設定画面すら満足に開けないという悲惨な状況に陥る.
Q. Webサーバでも,どうにかTIME-WAITを減らせない?
利用者の傾向によって,減らせるかもしれないし,減らせないかもしれない.あまり興味のない分野になるので,実測値に基づく実際的(practical)な方法ではなく,あくまで理論上での話を進める.
仮に,1分間に5つのページにアクセスするような利用者がいたとしよう.このとき,Keep-alive timeoutを5秒に設定すると,恐らくページ毎に新しくセッションを確立し,それがTIME-WAITとして残ることになる.じゃあ,Keep-alive timeoutを1分にするとどうだろう? 1回のセッション確立(同時接続数ぶん)で済む計算になり,セッション数は減少する.もちろん,1ページにしかアクセスしないユーザがいれば,1分間長くセッションを張り続けてしまうことにはなるので,適するケースと適さないケースがある.
TIME-WAITとは無関係になるが,mod_limitipconnなどを用いて接続数を制限することが有効な場合もある.
例えば,前述したような1分のKeep-alive timeoutを設定した上で,同時接続数を2に制限しよう.行儀の悪いブラウザがやってきて,8セッションも消費して1ページだけ取得してきたようなときを考える.
同時接続数を制限しない場合は,8セッションが Keep-alive 1分 + TIME-WAIT 2分 = 合計3分間残り続ける.かなり間違った考え方になるが,掛け算して 3分間 × 8セッション = 24分間 として計算しよう.同時接続数を制限した場合,2セッションが3分間,6セッションはTIME-WAITの2分間だけ残り続ける(mod_limitipconnがエラーを返してすぐ正常に切断する場合).掛け算して足し合わせると, 3分間 × 2セッション + 2分間 × 6セッション = 18分間 となる.
Q. 結局,私は何をすればいいの?
- 接続要求は,「ルータが転送しない(ルータの段階で拒否応答)」「サーバが受け入れる」「サーバが断る」のいずれかで応答すること.
- 「ルータでNATしておきながら,サーバがステルスモードで無応答」は避ける.
- クライアントに切断処理をさせる.
- サーバが切断すると,TIME-WAITが残る.
- 大変なときはポートを閉じる.
- TCP/IPスタックが拒否(RST/ACK)を返し,セッションはすぐ消滅する.
- バックログを適切に取り扱うような設計をする.
- 接続がいっぱいなら,TCP/IPスタックが拒否を返し,セッションはすぐ消滅する.
- Webサーバなら,同時接続数を制限したり,Keep-alive timeoutを延ばしたりする.
- ただし,効果は大きくない.Webサーバはかなり不利な立場にあると言える.
Q. なんでそこまでWHR-G54Sにこだわるの?
新しくルータを買うなんて!