hirax.net::inside out::2011年04月14日

最新記事(inside out)へ  |   年と月を指定して記事を読む(クリック!)

2011年3月 を読む << 2011年4月 を読む >> 2011年5月 を読む

2011-04-14[n年前へ]

「Ruby+Thinkpad」で作る地震震度計 

 地震が続く今日この頃、めまいと地震を区別できない…というシチュエーションのために、昨日は「お手軽な地震検知器」を作ってみました。今日は、その続きとして、Ruby(とIBM産ノートPCを使って)で地震検知器を作ってみることにしました。

 地震の震度は、大雑把に言えば、加速度と揺れ動く時間とその周波数で決まります。以前、ノートPCで作る地震警報システムを作ろうとしたことがあります。加速度センサを備えた機器は多いわけですから、身の回りにある機器で地震の震度を算出する…なんていうことは、実に簡単に「できる」ものです。

 今日は、以前作った「Ruby版 Thinkpad 加速度センサ類取得クラス」を使って、「地震の震度スクリプト」を書いてみました。ノートPC(Thinkpad)の内蔵センサからの加速度を得て、その上で「揺れ動く時間」と「その周波数」というパラメータを適当にネグった上で(=無視した上で)適当に加速度から揺れ動く(地震の)震度を近似計算するスクリプトを書いてみたのです。このスクリプトは、語句単純に「ruby hoge.rb "スクリプトを走らせる秒(s)数"」という風に走らせることで、100ms毎に検知した加速度から震度を計算し続けて、もしも地面が揺れていると判断された時には、地震の震度を一秒に一回づつ、たとえば、

3
5 (=震度5弱)
5.5 (=震度5強)
…
といったように表示する、というものになります。そのRubyコードは下のようになります。「Ruby版 Thinkpad 加速度センサ類取得クラス」を、このスクリプトと同じディレクトリにでも置いた上で、このスクリプトを実行させれば、上に示した例のように動きます。
require 'accelerometer'
include Math

waitSec=0.01 # = each 100ms
averageNum=(1.0/waitSec).to_i

def send si
  puts si
end

def process(gxy)
  si=nil
  si=1 if gxy> 0.5
  si=2 if gxy> 2
  si=3 if gxy> 5
  si=4 if gxy> 20
  si=5 if gxy> 40
  si=5.5 if gxy> 100
  si=6 if gxy> 140
  si=6.5 if gxy> 200
  si=7 if gxy> 400
  send(si) if si&&si>3
end

class Array
 def average
   val=0.0
   self.length.times{|i| val+=self[i] }
   return val/self.length.to_f
 end	 
end

period=ARGV[0].to_i*(1.0/waitSec).to_i
acc=Accelerometer.new
gdatum=Array.new(averageNum) {|i| 0.0 } 
gi=0
period.times do |i|
  gx,gy=acc.getAccelerometerData.map{|v| 
    980.0*tan((v.to_f)/50.0*22.5/360.0*6.28)}
  gdatum[gi]=sqrt(gx*gx+gy*gy)
  gi=gi+1
  if gi==averageNum
    process gdatum.average 
    gi=0
  end
  sleep waitSec
end

 Thinkpad(やそれと似た同類の危機)に搭載されている加速度センサでは、震度1とか2程度の震度を正確に検知することはできません(その理由は後ほど書きます)。…その一方で、「日本全国の机の上に置かれていて(スマートフォンは、残念ながら、机の上には置かれていないのです)、さらに、その機器を使って”震度”を算出することができる値を刻々計ることができる計測器」というものが、ノートPCほどちまたに溢れているわけでもありません。

 今日は、そんな貴重な道具を使ったスクリプトを書いてみました。こんなスクリプト、手元のPC向けのクライアント用スクリプトだけでなく ネットワークに接続しているたくさんの人たちが動かしたら一体どうなるか、ということについては、また明日にでも書いてみたいと思います。