今回は歩行履歴を取得する手順についてみていきます。
といってもGPSで簡単に取得できる屋外の移動ではなく、
屋内における、GPSよりも粒度の細かい移動履歴を取得することを目的とします。
今回は、スマートフォンの”加速度センサ”および”ジャイロセンサ”をHTML5経由で取得します。
ただし、リアルタイムに処理する事を想定し、
出来るだけ簡易なコードである程度の精度で実装することを目的とします。
まずスマートフォンにおける加速度センサとジャイロセンサについて簡単に説明しますと
加速度センサは”x,y,z軸でのデバイスの移動速度”を検出し、
ジャイロセンサは”x,y,z軸でのデバイスの回転速度”を検出します。
それぞれの向きは下記の通りとなります。
HTML5で上記の値を取得するためには、
加速度センサの場合、JS内でaddEventListener(“devicemotion”)として、
それぞれ、accelerationIncludingGravityから値を取得することができます。
具体的には下記の通りとなります。
1 2 3 4 5 |
window.addEventListener("devicemotion", function(motion_event){ var x = motion_event.accelerationIncludingGravity.x; var y = motion_event.accelerationIncludingGravity.y; var z = motion_event.accelerationIncludingGravity.z; }, true) |
同様にジャイロセンサは、JS内でaddEventListener(“deviceorientation”)として、
それぞれ、alpha(z軸回転)、beta(x軸回転)、gumma(x軸回転)から値を取得することができます。
具体的には下記の通りとなります。(ついでに回転角度を360度に変換)
1 2 3 4 5 6 7 8 9 |
window.addEventListener("deviceorientation", function(orientation_event){ var z_orientaiton = orientation_event.alpha; var x_orientaiton = orientation_event.beta; var y_orientaiton = orientation_event.gumma;} var z_degree = z_orientaiton.toFixed(1) * Math.PI / 180; var x_degree = x_orientation.toFixed(1) * Math.PI / 180; var y_degree = y_orientation.toFixed(1) * Math.PI / 180; }, true) |
まず、歩行履歴を取得するために、
“歩行中”というステータスを検出することにします。
スマホを持って歩行しますと、どうしても体が揺れ、加速度センサの値は大きくなり、
停止中は、そこまで体が揺れませんので、加速度センサの値は小さくなります。
よって、加速度センサを使用して、
“少し前の加速度”と”現在の加速度”の差の比率が
あるしきい値以上であれば”歩行中”と見なせる事ができそうです。
※逆に停止中は、”少し前の加速度”と”現在の加速度”に大きな違いは無い。
さて、通常の向きでスマホを持っている状態では、
実はz軸(つまり重量方向)のみの加速度変化だけでも、
かなりの精度で、移動中、かどうかを判定できます。
※歩行中は、体はz軸に揺れるということです。
しかし、ユーザがどのような向きでスマホを持っているか不明である事と、
より精度を上げるために、下記のような式で現時点の”体の揺れ”を表す事にします。
r = root(x*x + y*y + z*z)
x : x軸の加速度
y : y軸の加速度
z : z軸の加速度
上記rを、任意の期間ごとに合計したとき、
少し前の合計値と直近の合計値の変化量をもとめればよいことになります。
たとえば、配列を用いて0〜4の要素に、過去の”揺れ”、
5〜9を直前の”揺れ”を格納すると”体の揺れ”の変化量を求める事ができます。
ここまでの流れは以下の通りとなります。
※しきい値をどこまで厳しくするかは目的によって調整
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
var vibration = [0,0,0,0,0,0,0,0,0,0]; var time = 0; var walking_scalar=1.0; var top_threshold = 1.05; var bottom_threshold = 0.95; window.addEventListener("devicemotion", function(motion_event){ var x = motion_event.accelerationIncludingGravity.x; var y = motion_event.accelerationIncludingGravity.y; var z = motion_event.accelerationIncludingGravity.z; vibration[time] = Math.pow(x*x+y*y+z*z) , 2); time ++; if(time > 9){ if((vibration[0] + vibration[1] + vibration[2] + vibration[3] + vibration[4] ) / (vibration[5] + vibration[6] + vibration[7] + vibration[8] + vibration[9] + 0.000001) > top_threshold || (vibration[0] + vibration[1] + vibration[2] + vibration[3] + vibration[4] ) / (vibration[5] + vibration[6] + vibration[7] + vibration[8] + vibration[9] + 0.000001) < bottom_threshold ){ walking_flag = 1; }else{ walking_flag = 0; } time = 0; } }, true); |
ここまでで移動中かの判定ができますので、
もし移動中であれば、任意の単位移動量を移動時間に掛け合わせると、
移動量を算出することができます。
※たとえば、もし移動中であれば、1秒当たり1.5m進めるなど。
さて、このままですと、一定方向のみに歩行しているデータとなりますので、
“曲がった”ことを検出します。
現在、どの方向に歩行しているかは、”ジャイロセンサ”から、デバイスの回転角度を使用して、
おおよそ測定することができます。
1 2 3 4 5 6 7 |
if(walking_flag == 1){ old_x = old_x + walking_scalar * Math.cos( (-1) * alpha.toFixed(1) * Math.PI / 180 ); old_y = old_y + walking_scalar * Math.sin( (-1) * alpha.toFixed(1) * Math.PI / 180 ); latest_x = old_x + walking_scalar * Math.cos( (-1) * alpha.toFixed(1) * Math.PI / 180 ); latest_y = old_y + walking_scalar * Math.sin( (-1) * alpha.toFixed(1) * Math.PI / 180 ); } |
上記のlatest_x,latest_yの推移が、歩行データとなります。
なお、歩行データをhtml5 canvasなどで書き出すと、
リアルタイムでビジュアライズすることができます。
※上記(olx_x,old_y)、(latest_x,latext_y)を引数とした場合は、
下記の通りとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function drawLine(x1,y1,x2,y2){ var canvas = document.getElementById('canvas1'); if(canvas.getContext){ var context = canvas.getContext('2d'); context.strokeStyle = 'rgba(200,200,200,0.5)'; context.lineWidth = 3.0; context.beginPath(); context.moveTo(x1,y1); context.lineTo(x2,y2); context.closePath(); context.stroke(); } } |
なお、xcodeにおけるswiftでも、同様のことができますが、
さらに、「階段の上り下り」といった値も取得する事が出来ますので、
よりリッチなデータを取得することができるかと思います。
※swiftでの階段の上り下りは、主に気圧センサの値、
および加速度、ジャイロセンサから複合的に計測されているようです。
以上、今回は、歩行データの取得を見ていきました。