1.はじめに
Node-REDプログラムで、設定した範囲内に飛行機が入ると、「飛行機がもうすぐ来るよ」と音声で知らせてくれる面白いものがあります。飛行機が来ることだけでなく、どの方角に飛んでいるのか? そして飛行機が範囲内に来る予測を、心の欲するままにプログラムを考えて追加してみました。
2.追加したプログラム
(1)飛行機が飛んでいる方角:逆三角関数アークタンジェント(arctangent)で角度を算出。
(2)飛行機が来る予測:約10km(約1分) 飛行後、設定位置から半径10㎞範囲内に入るか判定。
(1)飛行機が飛んでいる方角(詳細)
設定位置からの飛行機の方角、角度(北から右回り)を計算して音声で知らせる。
①設定位置から飛行機位置までの距離、X(経度)とY(緯度)を引き算にて求める。
x= Number(msg.payload.lon); //飛行機位置(経度)を変数xに代入
msg.x=x-135.0162 //飛行機位置(経度) から設定位置(135.0162)を引く。
y= Number(msg.payload.lat); //飛行機位置(緯度)を変数yに代入
msg.y=y-34.7167 //飛行機位置(緯度)から設定位置(34.7167)を引く。
return msg;
②③飛行機位置の象限により、Switchノードにて、分岐させる。
④各象限ごとに角度計算をする。
下記は、1象限のプログラムを示し、詳細は後述で説明する。
なお、角度計算は、各象限ごとで、4パターンだと考えたが、結果は2パターンであった。
内容を分かりやすくするために、本プログラムは4パターンのままにしている。
msg.deg=90-(Math.atan(msg.y/msg.x)*180/Math.PI)
return msg;
⑤角度の小数点以下を切り捨て、文章にする。
msg.payload="飛行機が上空に飛んでいるよ"+String(Math.floor(msg.deg))+"度に"
return msg;
⑥音声出力する。
上記④の各ファンクションのプログラム(計算式)
第一象限と第四象限においては、90°を基準として、
第一象限では、90°からの引き算、第四象限では足し算で、飛行機の位置角度を求める。
第二象限と第三象限においては、270°を基準として、
第三象限では、270°からの引き算、第二象限では、足し算で、飛行機の位置角度を求める。
第二象限は、2つ上の図で示す通り【加算】であるが、
プログラム「msg.deg=270 - (Math.atan(msg.y/msg.x)*180/Math.PI)」は【マイナス符号】。
間違い? と思うが、xの値がマイナス、yの値がプラスであるため、「Math.atan(msg.y/msg.x)」の計算結果がマイナスとなり、
マイナス(計算結果)×マイナス(符号)は、プラス(加算)となり、正しい。
※第四象限の説明は、同じであるため省略する。
(2)飛行機が来る予測(詳細)
①約10km飛行後の設定位置との距離
xa= Number(msg.payload.lon); //<font color="Red">飛行機の位置(経度)をxaに代入
xa=xa+0.1*Math.sin(msg.payload.heading) // ※1
xa=xa-135.0162 //飛行機10km進行後と設定位置の差
xa=Math.pow(xa,2) //xaを2乗する。【三平方の定理 x方向の辺】
ya= Number(msg.payload.lat); //飛行機の位置(緯度)をyaに代入
ya=ya+0.1*Math.cos(msg.payload.heading) // ※1
ya=ya-34.7167 //飛行機10km進行後と接近を確認したい位置の差
ya=Math.pow(ya,2) //yaを2乗する。【三平方の定理 y方向の辺】
msg.z=Math.sqrt(xa+ya) //zの距離を求める。三平方の定理 斜辺】
return msg;
※1:飛行機が約10km進んだ先の位置(経緯度)を計算
約10kmは約0.1°である。この約0.1°に、三角関数にて、約10km進んだ先を算出する。
・約0.1°の求め方:360°×10㎞÷4万km(地球赤道1周)=0.09≒0.1°
(赤道=緯度0°なので、厳密な計算ではない。そもそも約10kmと適当なので気にしない)
・三角関数:経度方向は sin、緯度方向は cosである。
・msg.payload.headingは、飛行機の進行角度、北から時計回りにラジアン表示。
②半径10km以内?
msg.zの値が0.1(約10km)以内であるかを、Switchノードにて、判別する。