佐藤さとる

佐藤さとる

梶研 [技育展 & カルマンフィルタについて調べた]

2023年09月26日

技育展 & カルマンフィルタについて調べた

出席率

スケジュール

短期的な予定

長期的な予定

進捗報告

技育展

結果

ファイナリストなれず

改善点

感想等

ファイナリストには研究やOSSなど年単位で制作しているものが多く、

気軽に参加してファイナリストになれるものではないと感じた.

しかし、一部のファイナリストや企業賞を取っていた参加者の中には2ヶ月で制作したとうい人も多く、

制作期間だけではなく 技育展に適した アイデアなども重要だと思った.

端末姿勢推定

カルマンフィルタについて調べた

論文から

CiNii でカルマンフィルタを使っている研究論文を探した

GPS測位情報とセンサ情報に基づく位置推定システムに関する研究

IPSJ

移動体の電波強度を利用した歩行者の位置精度向上手法の評価

IPSJ

測距情報と姿勢情報と部屋情報を融合させた屋内位置推定システムに関する研究

IPSJ

加速度の時空間情報を考慮した進行方向推定手法の検討

IPSJ

論文は専門用語や未知の数学を使っていて難しかった.

Qiita 等

言いたいことは分かるが、数式が難しく計算方法がわからない

esa

相補フィルター

相補フィルターにも種類があることを知った

Youtube

とても分かりやすかった.

が、プログラムに起こした時の形が見えない

<iframe width="560" height="315" src="https://www.youtube.com/embed/zVAq_3HClGs?si=x7KggOX-ghEp3xRU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

Chat GPT

サンプルコードを生成してもらった.

プログラムから逆に考えてみる

<details><summary>生成したコード</summary><div>

import numpy as np
import pandas as pd

# カルマンフィルターの初期化
def initialize_filter():
    # 初期状態推定値 (クォータニオン)
    x = np.array([1.0, 0.0, 0.0, 0.0])  # 初期の姿勢は単位クォータニオン(姿勢なし)
    
    # 初期推定誤差共分散行列
    P = np.eye(4)

    # プロセスノイズの共分散行列 (システムノイズ)
    Q = np.eye(4) * 0.01  # 適切な値を設定する必要があります

    # 観測ノイズの共分散行列
    R = np.eye(3) * 0.1  # 適切な値を設定する必要があります

    return x, P, Q, R

# クォータニオンを角速度に変換する関数
def quaternion_to_rotation_rate(q, gyro_data):
    q_conj = np.array([q[0], -q[1], -q[2], -q[3]])
    omega = 2.0 * R.from_quat(q_conj).inv().as_rotvec() * gyro_data
    return omega

# カルマンフィルターの更新ステップ
def update_filter(x, P, Q, R, accel_data, gyro_data, dt):
    # 予測ステップ
    A = np.eye(4) + 0.5 * dt * np.array([
        [0, -gyro_data[0], -gyro_data[1], -gyro_data[2]],
        [gyro_data[0], 0, gyro_data[2], -gyro_data[1]],
        [gyro_data[1], -gyro_data[2], 0, gyro_data[0]],
        [gyro_data[2], gyro_data[1], -gyro_data[0], 0]
    ])
    x_pred = A.dot(x)
    P_pred = A.dot(P).dot(A.T) + Q

    # カルマンゲインの計算
    H = np.eye(3)
    K = P_pred.dot(H.T).dot(np.linalg.inv(H.dot(P_pred).dot(H.T) + R))

    # 角速度をクォータニオンに変換
    omega = quaternion_to_rotation_rate(x, gyro_data)

    # 観測更新
    x_updated = x_pred + K.dot(accel_data - H.dot(x_pred))
    P_updated = (np.eye(4) - K.dot(H)).dot(P_pred)

    return x_updated, P_updated

# メインプログラム
if __name__ == "__main__":
    # データをDataFrameから読み込む (仮のデータ)
    data = pd.read_csv('sensor_data.csv')  # ファイル名は実際のファイルに合わせて変更

    # カルマンフィルターの初期化
    x, P, Q, R = initialize_filter()

    # サンプリング時間
    dt = data['timestamp'].diff().mean()

    # データフレームをイテレートし、カルマンフィルターを更新
    for index, row in data.iterrows():
        accel_data = np.array([row['accel_x'], row['accel_y'], row['accel_z']])
        gyro_data = np.array([row['gyro_x'], row['gyro_y'], row['gyro_z']])
        x, P = update_filter(x, P, Q, R, accel_data, gyro_data, dt)

    # 推定された姿勢をクォータニオンからオイラー角に変換
    euler_angles = R.from_quat(x).as_euler('xyz')

    print(f"推定されたロール角度: {euler_angles[0]} rad")
    print(f"推定されたピッチ角度: {euler_angles[1]} rad")
    print(f"推定されたヨー角度: {euler_angles[2]} rad")

</div></details>

進路関係

なし

余談

心霊スポット行ってきた

春日井市の 千歳楼

IMG_5264.JPG (6.1 MB)
IMG_5269.JPG (6.9 MB)

サーモグラフィで撮ってみた

幽霊に温もりはあるのか

flir_20230921T140203.jpg (1.7 MB)
flir_20230921T140251.jpg (1.8 MB)

<iframe width="923" height="692" src="https://www.youtube.com/embed/J8H-u8B1zdY" title="千歳楼(春日井市)" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>