レンタルカートの耐久レースで走行ログを取ってみた#2

この記事の内容

  • (前の記事)計測のためのハードウェアの準備
  • (この記事)計測と走行データの分析

計測

DroggerRWPで位置情報を取得し、Andoroidのスマホアプリ「DroggerGPS」を使ってスマホにログを取る。

ログ取得のための設定は公式HPの解説がわかりやすいのでそちらをご参照いただくとして、この記事では私がどのように設定したか簡単に記載しておく。

RTK基準局の設定

高精度位置情報を取得するためのRTKという技術は、普通のGPSの衛星とデバイス間の通信に加え、地上の基準局との通信が必要になる。そこで、まず必要なのが基準局の設定である。今回は趣味用途なので市販の位置情報提供サービスは使わずに、無料で基準局の情報を発信してくださっている方のご厚意にあやかる形にした。無料の基準局の情報がまとめてあるページがこちらである。

今回は三重県桑名市のレインボースポーツで走行した。一般的に基準局は半径10km以内にあるといいとされているが、近くに無料の基準局はなかったので、今回は海の向こうの東浦の基準局を使わせていただいた。設定時の写真を貼っておく。

ログ取得の設定

ログは後で解析しやすいように馴染みのあるCSVで出力することとした。またログの開始/停止の操作忘れ防止のためにスピードフィルタを設定し閾値を5km/hとすることで、動き出したら自動でログが始まり、低速になれば自動でログが停止するように設定しておいた。(実際に使ってみて、この機能はとても便利だなって感じました。)こちらも設定時の画面を貼っておく。

ログのアップロード

取得したCSVデータはアプリからそのままクラウドへ送信することができる。私はgoogleドライブにログ用のフォルダを作ってそこに保存するようにしている。一旦設定してしまえば、ログの送信は一瞬で完了する。(これもとっても便利だなって感じてます。)操作はとても簡単で送信したいログを選んで、右上のおしゃれなボタンを押して、送信したい場所を選択するだけだ。

走行データの分析

Googleドライブ上に保存されたログを自分のPCにダウンロードして分析を開始する。市販のソフトを使った解析もできないことはないと思うが今回は自分でやってみたかったので、Pythonをつかって分析してみた。

①データの分割(1ラップごと)

耐久レースでは1スティント20〜30分走行する。そのデータを眺めてもカオスなだけなので、まずはデータを1ラップごとに分割する。分割方法はいろいろあると思うが、コントロールラインの座標を設定し、その座標の近くを通った時に1ラップとカウントするようにプログラムを書いた。具体的にはコントロールラインの座標とログデータのある時点での座標の距離を求め、その距離がある閾値以下の時に1周とカウントする。

②v-tグラフのプロット

サーキット走行を経験された方ならわかる方も多いと思うが、横軸に時間、縦軸に速度をとったグラフ(v-tグラフ)はタイムアップのために非常に強力なデータとなる。(反省すべき点が多く見えるので、落ち込むことにもなるが。。)今回はラップ数を選択して、そのラップのv-tグラフを出力できるように書いてみた。

③位置情報のプロット

今回のこだわりポイントである位置情報のプロット。ただプロットするだけだと面白くないので、速度に合わせて色を変えてプロットしてみた。走行ラインが綺麗にプロットされていることがわかる。精度の良いGPSを使っているので、走行ラインの議論にも使えるところがいいところだ。


import gpxpy
import matplotlib.pyplot as plt
%matplotlib inline
import folium
from folium.plugins import HeatMap
import pandas as pd
import numpy as np
import scipy.signal as sg
import datetime
import matplotlib.colors as cl

filename = '2021-12-05_13-08-17.csv'
data = pd.read_csv(filename)
data.time = pd.to_datetime(data.time)

ps = data.loc[:,['latitude','longitude']]
lat = data.latitude
lon = data.longitude
sp = data.speed

#コントロールラインの座標設定
control_line = [35.049354,136.616640]

norm = cl.Normalize(vmin=20, vmax=80)
henkan = plt.get_cmap('jet')

#時間差計算関数
def time_diff(time):
    time_s = time[0]
    diff = []
    for i in range(len(time)):
        diff.append((time[i] - time_s).total_seconds())
    return diff

#コントロールラインとの差分計算
def pos_diff(position):
    pos_d = []
    for k in range(len(position)):
        dpos = position[k,:] - np.array(control_line)
        pos_d.append(np.linalg.norm(dpos, ord=2))
    return pos_d

#走行ライン計算関数
def plotlap(run_no):
    id1 = minid[0,run_no]
    id2 = minid[0,run_no+1]
    lat_lap = lat[id1:id2]
    lon_lap = lon[id1:id2]
    v_lap = sp[id1:id2]*3.6
    V_lap = np.round(v_lap, decimals=0)

    pts = np.array([lat_lap,lon_lap]).T

    # 基準地点と初期の倍率を指定し、地図を作成する
    map1 = folium.Map(location=control_line,
                tiles='https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg',
                attr='レインボースポーツ 空中写真',
                zoom_start=20)

    # 基準地点にマーカーを設置する
    marker = folium.Marker(control_line, popup='home')
    map1.add_child(marker)

    for i in range(len(V_lap)):   
        p = folium.CircleMarker(location=tuple(pts[i,:]),
                radius=1,
                popup=None,
                tooltip=None,
                color=cl.to_hex(henkan(norm(V_lap[id1+i]))))
        map1.add_child(p)
    return map1

#v-tグラフ描写関数
def vt_graph(run_no):
    t_lap = t_diff[minid[0,run_no]:minid[0,run_no+1]] - t_diff[minid[0,run_no]]
    v_lap = sp[minid[0,run_no]:minid[0,run_no+1]]
    return plt.plot(t_lap,v_lap*3.6)

#ラップタイム計算関数
def lap_time(minid):
    lptm = []
    for i in range(len(minid.T)-1):
        ti = t_diff[minid[0,i+1]] - t_diff[minid[0,i]]
        lptm.append(ti)
    return plt.plot(lptm,'-o')

t = data.time
t_diff = np.array(time_diff(t))


#①データの分割(1ラップごと)
pos = np.array([lat, lon]).T
p_diff = np.array(pos_diff(pos))
minid = sg.argrelmin(p_diff, order=500) #最小値
minid = np.array(minid)
plt.plot(t_diff, p_diff, label='difference', c='c')
plt.plot(t_diff[minid],p_diff[minid],'ro',label='control_line')
plt.xlabel('time (s)')
#plt.legend(loc=0)
plt.show()

lap_time(minid)
plt.xlabel('Laps')
plt.ylabel('Laptime(s)')
plt.grid()
plt.ylim([70,80])

#②v-tグラフのプロット
run_no = 9
lap_time = t_diff[minid[0,run_no+1]] - t_diff[minid[0,run_no]]
print(lap_time)
vt_graph(run_no)
plt.title(lap_time)
plt.xlabel('time(s)')
plt.ylabel('velocity(km/h)')
plt.grid()
plt.ylim([20,80])
plt.xlim([0,80])

#③位置情報のプロット
plotlap(run_no)

おわりに

今回はレンタルカートの草レースで走行ログを取る方法について解説した。レースだけでなく練習走行の時間にも活用できる。ヘルメットとポーチを友人に渡すだけで簡単にログが取れるので、仲間内でログを比較してレベルアップに繋げるのにもおすすめだ。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です