Fitbitの表示する距離がどう違うのかを追う
こんばんは、Takum!でございます。
なんかのどが…乾燥中です。風邪ひかないようにしたいと思います。
今までFitbitとSTRAVAの距離がずいぶん違うな~というのを課題として、データを取り込んだり、地図に載せて仕様を勘ぐってみたりしていました。
今回は、その距離が何で違うのか、緯度経度情報から実際の距離を足し合わせて求めてみたいと思います。
今回使用するデータは、Fitbitのpickleのみです。fitbitが累積した距離と、各測定点の緯度・経度が入っています。
これらの緯度・経度の移動差分から、その距離を求める関数を定義します。この関数に用いている式は、ヒュベニ(ヒュベニイ)の式と言われているようです。なんでこの式になるのか、はまた別途説明したいと思いますが、今回はそのまま当てはめていきます。
moveが各ポイント間の距離です。それをcumsum()して、累積距離 distを求めています。
fit_distとdistを比べると、9394mと10863mと有意な差が出ています。実際、STRAVAのほうで保存したログの移動距離は11.03kmでしたので、上記の式で加算したほうがだいぶ精度が良さそうです。同じルートをGoogle Mapでトレースすると、10.7kmと出ました。やはりFitbitの数値はどうも小さすぎですね。累積距離をグラフ化してみましょう。
オレンジ色が緯度経度から計算した累積距離で、青がFitbitの出している数値です。どうやら、まんべんなく違っていますね。(予想としては、ログの一部が抜け落ちたりしているんじゃないか、と疑ったのがこの調査の発端だったのですが。)ということは、Fitbitの距離はヒュベニの式でない方法で求めているのか、気になるところであります。
また何か発見があったら共有したいと思います。
なんかのどが…乾燥中です。風邪ひかないようにしたいと思います。
今までFitbitとSTRAVAの距離がずいぶん違うな~というのを課題として、データを取り込んだり、地図に載せて仕様を勘ぐってみたりしていました。
今回は、その距離が何で違うのか、緯度経度情報から実際の距離を足し合わせて求めてみたいと思います。
今回使用するデータは、Fitbitのpickleのみです。fitbitが累積した距離と、各測定点の緯度・経度が入っています。
import pandas as pd import numpy as np import matplotlib.pyplot as plt df = pd.read_pickle('fitbit.pickle') df.tail()
fit_alt | fit_dist | fit_hr | fit_lat | fit_lng | |
---|---|---|---|---|---|
fit_日時 | |||||
2019-01-31 08:22:35 | 57.500000 | 9388.570312 | 117 | 38.259911 | 140.875702 |
2019-01-31 08:22:36 | 58.000000 | 9389.860352 | 117 | 38.259911 | 140.875702 |
2019-01-31 08:22:37 | 58.400002 | 9391.219727 | 116 | 38.259922 | 140.875702 |
2019-01-31 08:22:38 | 58.549999 | 9392.669922 | 115 | 38.259930 | 140.875717 |
2019-01-31 08:22:39 | 58.700001 | 9394.230469 | 115 | 38.259937 | 140.875717 |
これらの緯度・経度の移動差分から、その距離を求める関数を定義します。この関数に用いている式は、ヒュベニ(ヒュベニイ)の式と言われているようです。なんでこの式になるのか、はまた別途説明したいと思いますが、今回はそのまま当てはめていきます。
def calculateHubeni(latitude, lat_delta, lng_delta): a = 6378137 # 赤道面半径 f = 1 / 298.257222101 # 扁平率 theta = latitude / 180 * np.pi return np.pi*a*(1-f)*np.sqrt(lat_delta**2+lng_delta**2*np.cos(theta)**2)/(180*np.sqrt(np.sin(theta)**2+(1-f)**2*np.cos(theta)**2)) df['move']=calculateHubeni(df['fit_lat'], df.shift(-1)['fit_lat']-df['fit_lat'], df.shift(-1)['fit_lng']-df['fit_lng']) df['dist']=df['move'].cumsum() df.tail()
moveが各ポイント間の距離です。それをcumsum()して、累積距離 distを求めています。
fit_alt | fit_dist | fit_hr | fit_lat | fit_lng | move | dist | |
---|---|---|---|---|---|---|---|
fit_日時 | |||||||
2019-01-31 08:22:35 | 57.500000 | 9388.570312 | 117 | 38.259911 | 140.875702 | 0.000000 | 10859.817383 |
2019-01-31 08:22:36 | 58.000000 | 9389.860352 | 117 | 38.259911 | 140.875702 | 1.272308 | 10861.089844 |
2019-01-31 08:22:37 | 58.400002 | 9391.219727 | 116 | 38.259922 | 140.875702 | 1.579170 | 10862.668945 |
2019-01-31 08:22:38 | 58.549999 | 9392.669922 | 115 | 38.259930 | 140.875717 | 0.848205 | 10863.517578 |
2019-01-31 08:22:39 | 58.700001 | 9394.230469 | 115 | 38.259937 | 140.875717 | NaN | NaN |
fit_distとdistを比べると、9394mと10863mと有意な差が出ています。実際、STRAVAのほうで保存したログの移動距離は11.03kmでしたので、上記の式で加算したほうがだいぶ精度が良さそうです。同じルートをGoogle Mapでトレースすると、10.7kmと出ました。やはりFitbitの数値はどうも小さすぎですね。累積距離をグラフ化してみましょう。
fig, ax = plt.subplots() ax.plot(df.index, df['fit_dist']) ax.plot(df.index, df['dist']) ax.legend(loc='lower right') plt.show()
Fitbitの累積距離のグラフ。青がFitbitの示す数字、オレンジが緯度経度から計算した累積値。 |
また何か発見があったら共有したいと思います。
コメント
コメントを投稿
コメントをどうぞ。