Fitbitの表示する距離がどう違うのかを追う

こんばんは、Takum!でございます。
なんかのどが…乾燥中です。風邪ひかないようにしたいと思います。

 今まで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_altfit_distfit_hrfit_latfit_lng
fit_日時
2019-01-31 08:22:3557.5000009388.57031211738.259911140.875702
2019-01-31 08:22:3658.0000009389.86035211738.259911140.875702
2019-01-31 08:22:3758.4000029391.21972711638.259922140.875702
2019-01-31 08:22:3858.5499999392.66992211538.259930140.875717
2019-01-31 08:22:3958.7000019394.23046911538.259937140.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_altfit_distfit_hrfit_latfit_lngmovedist
fit_日時
2019-01-31 08:22:3557.5000009388.57031211738.259911140.8757020.00000010859.817383
2019-01-31 08:22:3658.0000009389.86035211738.259911140.8757021.27230810861.089844
2019-01-31 08:22:3758.4000029391.21972711638.259922140.8757021.57917010862.668945
2019-01-31 08:22:3858.5499999392.66992211538.259930140.8757170.84820510863.517578
2019-01-31 08:22:3958.7000019394.23046911538.259937140.875717NaNNaN

 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の示す数字、オレンジが緯度経度から計算した累積値。
オレンジ色が緯度経度から計算した累積距離で、青がFitbitの出している数値です。どうやら、まんべんなく違っていますね。(予想としては、ログの一部が抜け落ちたりしているんじゃないか、と疑ったのがこの調査の発端だったのですが。)ということは、Fitbitの距離はヒュベニの式でない方法で求めているのか、気になるところであります。
 また何か発見があったら共有したいと思います。


コメント

このブログの人気の投稿

MS Azure Information Protection を入れたら右クリックの「分類して保護する」がうざい