Search
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:
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ů.
SDA
0
SCL
1
VSYS
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ě.
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)
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
Š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
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'))
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))
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
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()