プログラムと電子工作の置き場、たまにコラム

日々のスニペットやMaker's系のプログラムを置いてきます。

RubyMineからVisual Studio Codeに移行しようかと思う

RubyMine から VSCode
いままでずっと業務などの比較的大きな規模のプロジェクトの開発にはRubyMine。ターミナルで書き捨て用のプログラムを書く分にはEmacsを使ってました。しかしながら、今後RubyMineの用途部分に関してはVisual Studio Codeでいいかなと思い始めてます。
理由はいくつかあるのですが、

  • LiveShareを会社で利用するため、既にVS-Codeを利用しており操作に慣れてきたこと
  • 無料であること
  • PHPを書くときにはPhpStormを起動したりしなくてよいこと

☝︎について補足しておくとIntelijやRubyMineにPHPのpluginを入れることはできます。

が大きな理由です。まあ年間使用料に関しては、CodeInspectionの機能だけで軽くペイしてくれると思ってるんですが。

CodeInspectionについて

RubyMineのCodeInspectionは素晴らしくてこれを代替えしてくれそうなものがVS-Codeの機能、プラグインには無いんですよね。
コード・インスペクション - ヘルプ | RubyMine

未定義の変数及びメソッドを利用したりすると教えてくれます。もちろんRubyはその言語仕様上、静的解析には限界があるので、ベストエフォート型。フォールスネガティブが多数にあるのは仕方ないんです。

以上の議論を踏まえると、ある程度自分自身で納得ができるCodeInspectionに相当する機能をVS-Codeで実現できれば、心置きなくVS-Codeに移行できそうです。そういった経緯からCodeInspectionの機能をVS-Codeで補うPluginの開発を行なって行きたいと思います。

CodeInspectionのPlugin
Type Annotationとかそういった方面からのアプローチではなくて、力技というか、

http://www.a-k-r.org/d/2014-09.html#a2014_09_19
https://naruse.hateblo.jp/entry/2017/05/16/164528

といった方法から取り組むことにしたいと思います。

進捗は随時、当Blogに書き込んで行きます。

ライト、ついてますか ワインバーグ追悼記事

PublicKeyで知ったのだが、G.M.ワインバーグさんが2018年8月7日この世を去ったそうだ。

彼はIT業界出身の有名なコンサルタントで特にソフトウェアエンジニアの間では高い知名度がある。

彼の著書「ライト、ついてますか―問題発見の人間学」には27、8歳の頃に出会い、30代中盤に差しかかろうとしている現在、内容を半分くらいは理解できるようになっただろうか?

しかしながら、いま確実に言えることは、問題発見、解決における自分自身の基礎の1つとなっているということだ。

手元に置いては、ふとたまに読み返したくなるし、これからもずっと参考にさせてもらう本なのだろう。

追悼の意味も込めて、私なりに咀嚼した考えをまとめてみたいと思う。

問題を解決することに魅了された人が多すぎる

特にソフトウェア開発者(およびそれに準ずる仕事への従事者)は問題を解決することに魅了されてる人が多いと思う。

ライト、ついてますかの根底を流れるテーマに、問題を解決しようとする以上に、正しく把握することのほうが重要だ。との考えがあるように理解している。

問題を解決するのが好きな人は問題が問題であるかを把握できない状況下で、それを問題にしてしまうことが多い。

しかしながらなぜそれが悪いのか?

それは、問題が真の問題ではないかもしれないことに加えて、解きたいと思えば思うほどそれが真の問題にすり変わっていくからだ。さらに悪いことに、その真ではない問題で多数の人を巻き込んでしまえば、真の問題ではないことを見抜く力が周囲にないのであれば、それが真の問題になってしまう可能性があるということだ。

ただし、多少の注意が必要かもしれない。直感的に問題だと感じたことが、真の問題であることが多いことも事実だからだ。

正しく問題の定義ができたかどうかの確信は決して得られることはないが、その確信を得ようとする努力はやめてはいけない。

他人の問題を解こうとするな

これも問題を解決することに魅了されてる人が抱える問題点の1つだ。他人の問題に首を突っ込みたくなる人は多い。

例えば同僚、上司の問題に首を突っ込みたくなった時には少し立ち止まり冷静に考えてみよう。

あなたの周りにいる人たちはきっとあなたと同じレベルの能力を持っている。あなたの周りにいる人たちの平均が今のあなたの能力だという言葉があるが、これは経験則的に正しいと考える。そのような人たちにあなたの助言はただのお節介だし、疎ましく思われる可能性すらある。

他人が自分の問題を自分で解決できる時にそれを解こうとするな。
あなたはやることがたくさんあるはずだ。自分自身のやるべきことに集中しよう。

問題解決だけが唯一の解法ではない

なぜなら問題とは、望まれた事柄と認識された事柄の相違であるから。
望まれた事柄に対する要求を落とす、もしくは現在の認識を変えることで解決となることもある。

ライト、ついてますか―問題発見の人間学を読み続ける理由

示唆に富んだアドバイスがこの他にもたくさんあるのだが、今までの話も踏まえて、私は普段以下の3つを気にかけるようにしている。

  • その問題は本当に問題なのか?
  • それは誰の問題なのか?
  • 問題を解決することが唯一の解法なのか?

これらの問いは問題の直接的な解法とはならないかもしれないが問題を把握するのに役立つ。さらに冒頭にも述べたように正しく問題を把握することは問題を正しく解決することの近道でもある。

この3つの気にかけによって、人間の間に発生する問題を多少上手く扱えるようになったように思う。さらに面白いと思うことは、問題に対する感じ方、捉え方というのは、年齢、経験を重ねる毎に違ってくるということだ。

それがこの本を定期的に読み返したくなる大きな理由なのだ。

緊急地震速報の受信端末を作る (3)コーディング編

利用規約的にOKの範囲なのかわからないのですが、Wather Newsの緊急地震速報(EEW)をTwitterでツィートしてるアカウントがいます。以下のようなデータ形式Twitterに投稿されます。

f:id:yuriai0001:20190107121104p:plain
eew_from_twitter

遅延時間のチェック

Twitterにツィートされるまでの時間を確認したかったので気象庁のサイトより緊急地震速報のデータを閲覧する。
このデータによると19時21分33.9秒に地震波を検出して、第一報が41.1秒、そして最終の第七報が22分21.3秒に送信されてます。

f:id:yuriai0001:20190107121146p:plain
eew_time

Twitterの投稿で秒数まで確認したい場合は、Twitter社で使われているStatus ID発行のアルゴリズムから逆算します。
github.com


Twitterへの投稿は第一報告が19時21分41秒、第三報が19時21分44秒と出ましたので、Twitter投稿によるレイテンシーは考えなくてよいという結果を得ることができました。

投稿内容をParseする

RubyTwitter Gemを使ってloopでTwitterへの投稿を取得。
StatusIDをチェックして前回取得時のものからIDが違うとスレッドを生成して内容をパースします。
gist.github.com

緊急地震速報を配信する

MQTTのようなプロトコルの方がIoTデバイス向けような気がしますが、現状HTTPを利用します。将来的にユーザーが増えることも考えて一応オブザーバーパターンを導入します。Observerはユーザーで、Subjectにeewを配信するmailmanというクラスを作成します。

gist.github.com


github.com


追記2018年8月
User Streams APIが廃止されたことによってTwitterによる提供を行なっていた緊急地震速報(EEW)が停止してしまいました。😫

緊急地震速報の受信端末を作る (2)理論編

まずは緊急地震速報の理論側をみていきたいと思います。

緊急地震速報は現在基本的に経験則に基づいたモデルを利用しています。震源地からの距離に比例して地震の揺れが弱くなることは一般的な想像できると思いますが、過去の地震データを参考に、最大振幅等を目的変数、マグニチュード震源距離、地盤条件などを説明変数として回帰分析して得られたものが距離減衰式です。

ということで、まずは震源距離を求める必要があります。

震源距離

ここで地球を球面とし、地球上の2点間距離、PQを以下で表すと

PQ間の距離は以下の式で求めることができます。
で、これは地球の半径(Km)です。

しかしながら、今回のような利用場面では直線での近似値を利用しても特に問題ないと思います。
説明の簡易性もあることから平面を採用するとして、その場合はピタゴラスの定理より

R : 震源距離(km)
k = 111.32km (経度1度)
Ax、Ay:活用地点の緯度・経度(単位:度)
Bx、By:震源の緯度・経度(単位:度)
D : 震源の深さ(km)

マグニチュード

地震の規模を示す値のマグニチュードには様々な種類があるのですが、その始まりの定義は震央距離⊿=100kmの位置に置かれた地震計で記録された最大記録振幅A(単位:μ)の常用対数を取ったものです。 この振幅を基準にした地震の規模を表す指標は、規模が大きな地震になると低周波域に波がシフトするためにMの数値に正確に反映されないという問題点がありました。

そこで、地震の断層運動のモーメントを表したモーメントマグニチュードが現在一般的に使われています。
日本国内では速報性にすぐれた気象庁独自の値である、気象庁マグニチュードも発表されます。
緊急地震速報ではこの気象庁マグニチュード(Mj)をモーメントマグニチュード(Mw)に変換して利用します。

宇津の経験式(宇津:1982)より。

ただこの宇津の経験式とモーメントマグニチュードはかなりの乖離が生じてしまうのですよね・・・。
 
この原因は地震の周波数の違いに起因するのだろうか。阪神大震災のように周波数が短い場合は、MwがMjに比べて低くでるのだけど、東日本大震災のような周波数が長いとその逆で宇津の経験式ではかなりの差がでてしまう。この経験式は1982年とかなり古い内容で、いまではデータもより新しいものがあるかと思いますので、ここらへん地震学者の方々には乖離の少ない式を作ってくれると嬉しいですよね。

最短距離

震源地から観測値までの最短距離を求めましょう。
地震は断層破壊によって起こるものであることから点で考えるよりも震源地は面で考える方が実態を反映します。宇津(1977)相似即によってMwから以下の式によって断層距離を求めます。

最大速度

地震の最大速度は工学的基盤という地表よりも硬い状態の地盤を対象として計算します。

D : 震源の深さ(km)
X : 断層最短距離(km)

地盤増幅率

地盤増幅率というのは地表面の地盤による地震波の増幅率です。
丘陵に比べて埋立地は増幅率が高いというのは感覚的に理解できそうです。地盤を統一的な手法により約1kmメッシュ及び約250mメッシュ区画で微地形区分として分類した地図から活用者側の地形データを調べます。

震度推定地点の計測震度

最後ににPGVから震度の変換については以下の関係式を使います。翠川・他(1999)

ふぅー。ざっと理論確認することができたので、コードを書いていきましょう。

本来であればスクリプト言語で書く分野ではないと思いますが、今回はラピットプロトタイプングなのでRubyを使っていきます。

gist.github.com

緊急地震速報の受信端末を作る (1)動機編

地震って怖いですよね。日本は地震大国でどこに住んでても避けようがないものだと思います。

そんなわけで、突然の地震から身を守れるようにと、スマートフォンにはゆれくるコールを入れて心の安寧を保っているのですが、スマートフォンって自宅だと電池が切れてしまったりしていることが多いんですよ。更に悪いことにiOS端末の場合はマナーモード時には音がなりません。(普通携帯電話って大抵マナーモードなのでは?)これはApple側の仕様なのでゆれくるコールのほうで対応のしようがありません。

もし、iPhoneで音がなったという場合はETWSを使ったのかもしれません。
ETWSについてはこちらをご覧ください。

第544回:ETWS とは - ケータイ Watch Watch

とにかく、より最適なインターフェースを求めて自作したいなと思うに至ったわけです。

受信端末の仕様

仕様を考えてみると以下を満たしたいですね。私だけではなくてこの記事をみた誰でも作成できるようにするためです。

  • 卓上固定端末
  • 喋る
  • 24時間365日安定稼働
  • 汎用パーツが使える
  • 安い

構築が楽で汎用的といえば、Arduinoもしくは昔かったRaspberryPiが家に転がってるのならそれを使うのが手かなと思います。

そもそも緊急地震速報って

そもそも緊急地震速報って何かを知らなければいけません。一言で説明するなら、緊急地震速報とはPrimary波とSecondary波の伝わる速度差を利用したものです。 P波よりもS波の方が振れ幅が広く、P波は上下動、S波は水平動が特徴です。その言葉通り地盤を伝わる速度に差があり、観測地点にはS波が先に到達します。 よく大きな地震を経験した人の言葉で、小さな揺れがきた後にその後大きな地震が来たという体験談をよく聞きますが、これはP波とS波の事を指しているものです。

気象庁により全国各地に設置されている観測機器でこの2つの波を補足して警報を出すというのが、緊急地震速報の仕組みです。

警報と予報

緊急地震速報には警報と予報があります。 気象庁の定義では、

一般向けの緊急地震速報(警報)は、最大震度5弱以上を予測し、2地点以上の地震計で観測された場合に、予測震度4以上の地域に対して発表する。
高度利用者向けの緊急地震速報(予報)は、地震の規模(マグニチュード)が 3.5 以上または最大震度3を予測した場合に、1地点の地震計で観測した場合も発表する。
とあります。私たちがTVやラジオもしくはインターネット端末で受信する場合は一般向けの警報となります。

大きな地震がくるので揺れに注意してください。というもので基本的には震度がどれくらいで、到達時間は何秒後かという通知はありません。

一方高度利用者向けというのは、高度利用者というだけあって、一般向けよりもより不正確だが早い段階での発表を行います。その名前の通り個人というよりも産業分野でより早い段階で情報を得たい方々向けですね。

高度利用者向けの受信端末を作るのは届出制となっているのですが、今回は個人利用なので特に問題ないでしょう。

FYI
ちなみに私は地震学を専門に学んだことはありません。

Raspberry Pi2を無線にてインターネット接続する。

ラズパイを無線にて接続します。

OS: RASPBIAN Debian Wheezy Kernel version:3.18

有線でSSH接続が必要なのでまずはLanケーブルを接続します。
モニターがあれば直接割り振られたアドレスを確認できますが、今回は周辺機器がない場合を想定します。

Macならターミナルからnmapを使用できますし、WindowsならGUIのソフトウェアを使っても構いません。詳細は以下を確認してください。
mrprc.stores.jp


nampを使う場合は自分のipアドレスを調べます。Macであれば、環境設定→ネットワークを選択すると現在のipアドレスが表示されます。仮に192.168.0.5とした場合、その他のデバイスは192.168.1.0/24(この場合192.168.0.1 ~192.168.1.255をスキャンする)にnmapします。

以下の結果が返ってくるかと思いますので、192.168.0.7にSSHで接続します。
Nmap scan report for 192.168.0.7
Host is up (0.014s latency).
PORT STATE SERVICE
22/tcp open ssh

$ssh pi@192.168.0.7
パスワードの初期値はraspbianです。

ここで、無線Lanの子機をRaspberry Piのusb端子に差し込みます。
自動で認識しますので、

$lsusb

と実行するとデバイス名が表示されるのを確認してください。

Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 004: ID 0411:01a2 BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNM Wireless LAN Adapter

その後ネットワークの設定を行います。

 $ sudo vim /etc/wpa_supplicant/wpa_supplicant.conf

テキストエディタで開いて
以下を追加します。

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
   ssid="今回接続したいssid"
   proto=WPA2
   key_mgmt=WPA-PSK
   psk="psk"
}

ssid、pskは大抵の場合、お使いの無線機器に貼り付けてあるシールに記載があります。
設定が終了したら、再起動してください。
$reboot

サーボモーターを動かす

サーボモータと言えばラジコン等でよく目にすることが多いですが、
どのようなものかというと下記の動画をご覧いただくのがよいと思います。

How to do Flag waving directly on Raspberry Pi with no add-on board - YouTube

wikipediaによるサーボモーターの項目によるとホビーユースのサーボモーターでは
標準規格化されていないと書いています。

確かにサーボモーターのデータシートを見ると
各社で数値採用している数値は、統一されていない印象があります。

このサーボモーターを制御するためには、LEDの項目で出てきた、PWMのパルス信号を送ります。
ある一定の周期でパルスを送るのですが、このパルス幅に応じてモーターの目標角度が決まります。
f:id:yuriai0001:20141227101955p:plain
サーボモーターは連続して回転できるわけではないため、角度は0度~概ね180度までしか動作しないことに注意してください。

今回利用するサーボモーターにはメーカー標準のデーターシートが見つからなかったため、
TowerPro SG90 Servo Specifications and Reviews
上記で確認しました。

パルスの周期は?になっており、 パルス幅は5-24msのようです。
先ほど標準規格がないと書きましたが、他の個体のパルス周期は15~20msが標準で採用されている
ようなので、今回は20msを採用してみましょう。

今回はおなじみの、WiringPiとC言語を使ってパルスを制御していきます。
マイコンによるPWM制御に関して、興味を持った方は、他の専門書を参照いただくことにして、
ここではまず、サーボを動かすことを最終目的に取り組んでいきます。

Raspberry Piの内部電源だけでなく、電池を利用して電力を供給します。
市販のアルカリ電池、もしくはエネループのような充電式でもOKです。


サーボモーターからは3本の線がでており、コネクターにつながっていますが、
オレンジはGPIO18 につながるように、 赤:電池のプラス 茶色:GNDに接続します。
また、1kオームの抵抗をサーボが故障した場合を考えて、配置しておきます。
サーボモーターのワイヤーの色は違いますが、回路図を参照してください。

f:id:yuriai0001:20141227125906j:plain

設定数値等参考にさせていただきました。
RaspberryPiとWiringPiでサーボを動かす - Qiita

#include <stdio.h>
#include <wiringPi.h>
int main()
{
pinMode(18,PWM_OUTPUT);
pwmSetMode(PWM_MODE_MS);
pwmSetClock(400);
pwmSetRange(1024);

while(1){
    int num;
    scanf("%i",&num);
    printf("%d\n",num);

    if(num == -1){
      break;
  }
    pwmWrite(18,num);
  }
    return 0;
 }

これを前回の、圧電スピーカー時と同様に、コンパイルしてあげます。
圧電スピーカーで音階を奏でる - Raspberry Pi 電子工作

プログラムを起動したのちに、パルス幅をコンソールに入力することによって、サーボモーターの角度が変化します。上記サイトの例にならい、24、115と入力するとサーボが動くのを確認できると思います。


いままで、Raspberry Piを使った様々な電子工作プログラムを試してきましたが、例えば、サーボであったり、温湿度センサーであったり、比較的安価な値段で購入することが可能です。

特に秋月電子さんは豊富な品ぞろえと通販にも対応しており、非常におすすめできるお店です。
秋月電子通商 トップページ - 電子部品・半導体 【通販・販売】
今後、自分で工作を考えるときにはこのようなお店でパーツを自主的に入手しましょう。
https://mrprc.stores.jp/items/57da4b629821ccec24000459