10. Strojové učení

Cíle cvičení

  • Seznámení výstupem z 9DOF IMU MPU9250
  • Rozpoznání náklonu akcelerometru
  • Interpretace IMU dat

Další zdroje

Rozpoznání náklonu z akcelerometru

Cílem této úlohy je natrénovat SVM klasifikátor tak, aby rozpoznal přibližné naklonění akcelerometru. Abychom toho mohli dosáhnout, je třeba projít těmito kroky:

  1. Získání trénovacích dat
  2. Označení trénovacích dat (štítky)
  3. Natrénování modelu
  4. Predikce v reálném čase

Získání trénovacích dat

Modul 10 DOF IMU je připojen k RPi pomocí sběrnice I2C. Vyberte vhodné piny (např. SDA na pin 0 a SCL na pin 1) a modul připojte, pro napájení zvolte pin VSYS. Z githubu stáhněte moduly mpu9250.py, mpu6500.py a ak8963.py. Stažené moduly uložte do paměti RPi. Nádledující kód přečte data ze všech dostupných senzorů.

import utime
from machine import I2C, Pin
from mpu9250 import MPU9250
 
i2c = I2C(0, scl=Pin(1), sda=Pin(0))
sensor = MPU9250(i2c)
 
print("MPU9250 id: " + hex(sensor.whoami))
 
while True:
    print(sensor.acceleration)
    print(sensor.gyro)
    print(sensor.magnetic)
    print(sensor.temperature)
 
    utime.sleep_ms(1000)

Jedná se o data typu float, takže je nutné promyslet, jak data efektivně přenést a případně uložit. S ohledem na rychlost přenosu a potřebnou přesnost může být výhodné přenášet data binárně.

V Pythonu pak lze pro přenost a dekódování dat ve strukturách podobným jako v C využít knihovny ctypes nebo struct.

PC - příjem a uložení

Pro offline analýzu uložte data do souboru ve formátu CSV. To lze udělat např. pomocí modulu csv. Následující kód předpokládá, že jsou data získána (ze sériového portu, z databáze, z API rozhraní služby) ve formě seznamu.

import csv
 
header = ['acc_x', 'acc_y', 'acc_z', 'gyr_x', 'gyr_y', 'gyr_z']
data = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
 
with open('data.csv', 'w', encoding='UTF8', newline='') as f:
    writer = csv.writer(f)
 
    # write the header
    writer.writerow(header)
 
    # write the data
    writer.writerow(data) 

Přiřazení štíků

Rozpoznání náklonu akcelerometru je velmi jednoduchá klasifikační úloha. Hledané třídě (náklonu) odpovídá kombinace diskrétní hodnot, získaných z IMU. Nasbíraná data rozdělíme do tříd tak, že do jednotlivých řádků doplníme jednoznačný štítek, např. takto

  • 0 - vodorovně
  • 1 - náklon dopředu
  • 2 - náklon dozadu

Štítky nemusí být číselné, může to být i textový řetězec. Příklad výsledného souboru:

acc_x,acc_y,acc_z,gyr_x,gyr_y,gyr_z,class
0.076416015625,-0.04150390625,1.00341796875,0.030517578125,6.591796875,0.9307861328125,0
0.1044921875,-0.04052734375,0.851318359375,-2.95257568359375,9.6435546875,-0.38909912109375,0
...
0.173583984375,0.426513671875,0.89892578125,2.99072265625,10.36834716796875,1.8768310546875,1
0.146728515625,0.327392578125,0.689697265625,3.692626953125,4.31060791015625,4.6844482421875,1
...
-0.076904296875,-0.660888671875,0.782958984375,5.767822265625,2.02178955078125,2.4566650390625,2
-0.1162109375,-0.67138671875,0.619384765625,6.44683837890625,-15.106201171875,-0.61798095703125,2

Trénování klasifikátoru

Uložená data použijeme jako trénovací (70% dat) a testovací (30% dat) množinu pro získání klasifikátoru.

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import svm
import pickle
 
dataset = pd.read_csv('data.csv')
X = dataset.iloc[:, [0, 1, 2, 3, 4, 5]].values
y = dataset.iloc[:, [6]].values
 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.30, random_state = 0)
 
clf = svm.SVC(kernel='linear')
clf.fit(X_train, np.ravel(y_train))

Klasifikátor je možné uložit pro pozdější použití např. pomocí modulu pickle.

filename = 'model.sav'
pickle.dump(clf, open(filename, 'wb'))

Predikce

Pokud máme k dispozici model, je možné použít předikci z dat, které v reálném čase získáváme z IMU:

clf = pickle.load(open('model.sav', 'rb'))
# ziskani dat
D = [[data.acc_x, data.acc_y, data.acc_z, data.gyr_x, data.gyr_y, data.gyr_z]]
# predikce
print(clf.predict(D))

IMU interpretace

pitch = 180 * atan2(acc_x, sqrt(acc_y*acc_y + acc_z*acc_z))/PI;
roll = 180 * atan2(acc_y, sqrt(acc_x*acc_x + acc_z*acc_z))/PI;

Vyzkoušejte vypočítat hodnoty a zamyslet se nad tím, jaké výsledky získáváte.

Další linky:

https://silo.tips/download/application-note-imu-visualization-software

https://github.com/jarzebski/Arduino-ADXL345

http://davidegironi.blogspot.com/2013/02/avr-atmega-mpu6050-gyroscope-and.html#.YnpJnZYzXrc

https://www.instructables.com/Arduino-MPU6050-GY521-6-Axis-Accelerometer-Gyro-3D/

https://www.slideshare.net/dibaowang/imu-general-introduction

Kód pro vizualizaci dat z gyroskopu

Předpokládejme, že ve třech prvních sloupcích CSV souboru jsou data přečtená z gyroskopu. Jejich vizualizaci můžeme provést např. takto:

from mpl_toolkits import mplot3d
import pandas as pd
import matplotlib.pyplot as plt
 
data = pd.read_csv('data1.csv')
 
ax = plt.axes(projection='3d')
 
x = data.iloc[:,0]
y = data.iloc[:,1]
z = data.iloc[:,2]
 
ax.scatter3D(x, y, z, color='green')
plt.show()

courses/b0b37nsi/tutorials/10.txt · Last modified: 2024/04/24 11:57 by viteks