feature image

2018年12月10日 | ブログ記事

震度計の実用化を目指す話(あとJuliaの紹介)

この記事はtraP Advent Calendar2018 12月10日の記事です。
計算の講義を活かして震度計を作った話の続編となっています。未読の方は前回の記事をご覧になってからお読みいただくことをおすすめします。

前回までのあらすじ

Raspberry piを使って震度計を作りました。実装はC言語です。

前回の反省

前回震度の計測はできるようになりましたが, 一方でトリガーがないので手動で計測を開始しなければなりませんでした。今回はそこについて修正を加えたいと思います。

前回の最後の実験で触れたように, 加速度センサーの精度はあまり良くなく, 平常時でも震度3程度を計測してしまうため, 常に測定し続けても意味がありません。なので震度5以上の大きな地震に絞って測定してみましょう。
ところで緊急地震速報の発表条件[1]を確認してみると, 最大震度5弱以上の地震が見込まれるときとあります。ということで今回はこれをトリガーとするものにしてみたいと思います。

情報源

ところで緊急地震速報はどうやって受信すればいいのでしょうか。気象業務支援センターによれば[2], テレビやラジオ等で入手できる他, 同センターや各配信事業者と契約を結ぶ方法があると書いてあります。
これはかなり面倒ですね。どうにかして楽に入手する方法はないのでしょうか。

電子工作では, NHKのラジオを常時受信し, チャイム音を聞き取って緊急地震速報発報を確認する方法があるようです[3]。しかし自分にはそこまでの技術力はありません。
また以前はTwitter上に緊急地震速報のデータを垂れ流してくれる素晴らしいBotがいましたが, Streaming API廃止に伴いBotも停止してしまいました[4]
何か他に手段はないかなと探してみましたが, 次のサービスを応用すればうまく行きそうです。

防災科学研究所の提供する新強振モニタでは, 全国各地のリアルタイム震度[5]と, 緊急地震速報の確認をすることができます。
この新強振モニタですが, 検証してみると毎秒jsonを取得していることがわかります。URLにはeewの文字もあり, どうやらここから緊急地震速報の発表状況を取得しているようです。試しに気象庁の緊急地震速報の発表履歴[6]とjsonを数例突き合わせてみるとどうやらそれに間違いないようです。
ということでこのページを毎秒叩けば確認できることがわかりました。次に取得したjsonの中身について確認したいのですが, その前に緊急地震速報について概説しておきます。

緊急地震速報とは

緊急地震速報は発表要件や内容によって警報と予報の2つに分類されます。
緊急地震速報は最大震度5以上の地震が発生することが予期されるときに発表されるものと説明しましたが, 厳密にはこれは誤りで, 正確には警報の方の発表要件です。
予報の発表条件は次のとおりです[7]

① 観測点における加速度振幅が 100gal を超えたとき(レベル法)
② 推定マグニチュードが 3.5 以上か、予想最大震度が3以上となったとき

従って警報が発表されたときには同時に予報も発表されることになります。
また, 緊急地震速報には更新があり,それぞれ発表・更新された順番に第1報, 第2報, ...... と呼ばれます。一般に報を重ねるごとに精度は向上していくようです。 そしてある程度精度が高まったら最終報を出し, 終了要件を満たした場合には緊急地震速報が終了します。
さらに, 計測機の誤検知と推定される場合にはキャンセル報が発表されることがあります。

今回は最大震度5以上であればよいので, 予報は使わず警報のみを用いることにします。

jsonの解析

どこかにjsonの中身の説明があると良いのですが, 表立って公開されているわけではないのでそのようなものはないようです。ということで先程突き合わせた結果による推察によって簡単に示しておこうと思います。

key type 概要
result object 省略
report_time string(datetime) 取得時における最近の速報発表時刻
region_code string 不明
request_time string(integer) jsonの出力された時刻
region_name string 緊急地震速報が発表された地域名
longitude string(float) 震源の東経
is_cancel string(boolean) キャンセル報か
depth string 震源の深さ
calcintensity string 予測される最大震度
is_final string(boolean) 最終報か
is_training string(boolean) 不明
latitude string(float) 震源の北緯
origin_time string(integer) 地震発生日時
security object 省略
magunitude string(float) 推定されるマグニチュード
report_num string(integer) 本発表が第何報であるか
request_hypo_type string 不明
report_id string(integer) 地震波検知時刻(?)
alertflg optional string("警報"or"予報") 本発表が警報か予報か

実装する前に

ここまで推察してみましたが,今回使うのはalertflgだけです。
実装はPythonでさっさと済ませようと思ったのですが, 実験がてらJuliaで書いてみることにしました。

Juliaとは?

ちょっとだけ紹介をしておきます。

Julialang
https://julialang.org/

公式サイトから特徴となりそうな部分を引っ張ってみると,

つまり早くてスクリプト言語っぽさがある動的型付けだけど型の明示もできてOOっぽくも関数型っぽくも書けるという特徴を持ったコンパイル言語らしいです。
ただしコンパイル言語といってもJITコンパイラによって実行時にコンパイルが行われます。
文法はMATLABに似ているらしく(ただし筆者は書いたことがない), indexが1から始まり, 標準で行列積などがサポートされているなど応用数学などとの親和性が高い言語となっています。

ところでこれは余談なのですがjuliaを調べるときはjulialangとかで調べると良いと思います。

Juliaのインストール

私のRaspberry PiではRaspbianを使っていますが, aptで入れようと思ったらv0.5.1とかいう激古具合(最新の安定版はv1.0.2)だったのでソースからビルドすることにしました。JuliaBerry[8]というサイトがあったのでそれを見ながらやってみます。

The Hard Part

The hardest part is waiting. On a Raspberry Pi 3 Model B+, the initial build takes 12+ hours. Subsequent builds after creating the Make.user file as described above should only take around two hours.[9]

は?(前日から記事を書き始めるものぐさ並の気持ち)
あ(手元のラズパイは初代model Bなので更に遅くなることを覚悟した気持ち)

実装

仕方ないので書くだけ書いておきましょう。
手始めに, 今回はHTTPクライアントとJsonのパーサが必要です。これらは公式からライブラリが公開されています。
ライブラリのインストールには, Pkgを使います。Pythonでいうpipに当たるものです。
まずJuliaを起動して次のとおり入力します。

using Pkg
Pkg.add("HTTP")
Pkg.add("JSON")

これでインストールされます。また, ライブラリの初回使用時にはプレコンパイルが入るのでさきに適当に使ってみると良いでしょう。
実際に書いてみるとだいたい次のような感じになります。

using HTTP, JSON, Dates

url = "http://www.kmoni.bosai.go.jp/new/webservice/hypo/eew/"
cexefile = ""

function getNowDateTime()
    nt = now()
    y = string(year(nt))
    mo = lpad(month(nt), 2, "0")
    d = lpad(day(nt), 2, "0")
    h = lpad(hour(nt), 2, "0")
    mi = lpad(minute(nt), 2, "0")
    s = lpad(second(nt), 2, "0")
    return y * mo * d * h * mi * s
end

function isAlertedNow(js)
    p = JSON.parse(js)
    return haskey(p, "alertflg") && p["alertflg"] == "警報"
end

function getJson()
    return String(HTTP.request("GET", url * getNowDateTime() * ".json").body)
end

while true
    if isAlertedNow(getJson())
        res = ccall((:measure, cexefile), Float64, ())
        println(res)
    sleep(1)
end

かなり簡単にかけました。ただ本当に動くかどうかは確かめていません。実行環境がないので。
JuliaはCを呼び出すのも簡単にできます。

res = ccall((:measure, cexefile), Float64, ())

ファイルパスと関数名, 返り値と引数の型を指定してあげるだけです。

おわりに

緊急地震速報の下調べをしてデスクトップ環境にJuliaを構築しているあたりまではまだ楽しかったのですが, Raspberry pi上にてビルドが間に合わないことを理解してからは無の気持ちでやっていました。
しかしこれがうまくいけばちゃんとした震度計になります。また, JuliaBerryではGPIOPinを制御するライブラリもあるようなのでfft含めてすべての実装をJuliaで行うことも難しくはなさそうです。
機会があったらこっちにも取り組んでみようと思います。

明日の担当はyasuくんです。お楽しみに。


  1. 気象庁|緊急地震速報|緊急地震速報(警報)及び(予報)について ↩︎

  2. 緊急地震速報 ↩︎

  3. 準入賞作品 緊急地震速報受信機の製作 | トランジスタ技術 ↩︎

  4. @eewbot ↩︎

  5. リアルタイム震度は前回示した算出式から求められる震度ではなく, 即時性がある方式によって計測震度を擬似的に算出したもののようです。 ↩︎

  6. https://www.data.jma.go.jp/svd/eew/data/nc/rireki/rireki.html ↩︎

  7. 緊急地震速報の概要や処理手法に関する技術的参考資料(pdf) ↩︎

  8. https://juliaberry.github.io/ ↩︎

  9. https://juliaberry.github.io/compile.html ↩︎

RLook icon
この記事を書いた人
RLook

アイコンはどこかの生徒会書記です。

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

ERC20トークンを用いた宝探しゲーム(真)の提案【アドベントカレンダー2018 10日目】 feature image
2018年11月3日
ERC20トークンを用いた宝探しゲーム(真)の提案【アドベントカレンダー2018 10日目】
Azon icon Azon
2018年12月23日
LogicProXでのサラウンド設定,オーケストラ用テンプレ作成,その他の小ネタ
SolunaEureka icon SolunaEureka
2018年12月16日
ICPCアジア地区横浜大会参加記【アドベントカレンダー2018 52日目】
eiya icon eiya
2018年11月30日
Flutterでスマホアプリを作ってみ(た | よう)【アドベントカレンダー2018 37日目】
Fourmsushi icon Fourmsushi
2018年12月23日
線形解読法
nari icon nari
2018年12月3日
ハル研究所プログラミングコンテスト 2018に参加しました[アドベントカレンダー2018 40日目]
ninja icon ninja
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記