MPU6050 3D Tracking
2017-03-27T16:34:20+02:00
2017-03-28T11:31:18+02:00
2022-08-10T14:30:30+02:00
bence1971387
Sziasztok!

Korábban már írtam ide, egy virtuális dobot szeretnék készíteni.

A problémám az lenne, hogy ugyan a szenzorból kapok adatokat, az én elgondolásom szerint egy gyorsulásmérő az adott tengelyen lévő sebesség változást méri, de annak nulla közeli értéknek kéne lennie bármilyen helyzetben, ha nem mozog a szenzor. Ennek ellenére inkább működik giroszkópként, mint gyorsulásmérőként. A térben bárhova helyezem, csak az orientációját adják vissza az alábbiak. Hogyan tudnám megoldani azt, hogy az adatok ténylegesen használhatóak legyenek térbeli lekövetésre?

Keresek már egy jó ideje, de nem sok infót találtam ezzel kapcsolatban kivéve a Kálmán-szűrőt ami jó kis algoritmus lehet ehhez a későbbiekben, de először használhatóvá kéne tennem az adatokat.

Arduino kód:

// MPU-6050 Short Example Sketch // By Arduino User JohnChi // August 17, 2014 // Public Domain #include<Wire.h> const int MPU_addr=0x68; // I2C address of the MPU-6050 int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; void setup(){ Wire.begin(); Wire.beginTransmission(MPU_addr); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) Wire.endTransmission(true); Serial.begin(38400); } void loop(){ Wire.beginTransmission(MPU_addr); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) Serial.print(AcX); Serial.print(" "); Serial.print(AcY); Serial.print(" "); Serial.print(AcZ); Serial.print(" "); Serial.print(GyX); Serial.print(" "); Serial.print(GyY); Serial.print(" "); Serial.println(GyZ); }

Python kód:

# -*- coding: utf-8 -*- import serial import time import sys,os ser = serial.Serial('/dev/ttyUSB0') ser.baudrate = 38400 ser.bytesize = 8 # a várt bytek száma ser.parity = 'N' ser.stopbits = 1 ser.timeout = 1 t = 0.001 acc = [0,0,0,0,0,0] old_speed = [0,0,0,0,0,0] old_position = [0,0,0,0,0,0] new_speed = [0,0,0,0,0,0] new_position = [0,0,0,0,0,0] multiple = 100000 rounded = [0,0,0,0,0,0] for a in range(10): ser.readline() #for ciklus vége while True: for a in range(6): time.sleep(t) data = ser.readline() data_array = data.split(' ') data_array[0] = int(data_array[0]) - 1577 data_array[1] = int(data_array[1]) + 180 data_array[2] = int(data_array[2]) + 879 data_array[3] = int(data_array[3]) + 114 data_array[4] = int(data_array[4]) - 23 data_array[5] = int(data_array[5]) + 36 acc[a] = float(data_array[a]) new_speed[a] = old_speed[a] + acc[a] * t new_position[a] = old_position[a] + new_speed[a] * t rounded[a] = round(new_position[a]*multiple,1) #for ciklus vége os.system('clear') print "X: ",rounded[0],"Y: ",rounded[1],"Z: ",rounded[2] #while ciklus vége ser.close()
Üdv: Bence
Mutasd a teljes hozzászólást!
Ez nem feltétlen programzási feladat lesz elsőre, szerintem gyere át a hobbielektronika oldalra, ott van Arduino topic.

Elsőre több észrevételem is van. A szenzor visszaad neked valami értéket, de egyelőre nem tudni, hogy az milyen skálán mozog. Nem mindegy, hogy a szenzor érzékenysége 2,4,8,16 g
-re van állítva, valamint az sem mindegy, hogy az adott szenzor milyen típusú számot ad vissza, de az most mindegy.

Innen példa:

How to read a gyro/accelerometer




Ha pl 2g-re van beállítva és a mért adat 1944, akkor pl ax=(1944/16384)*9,81

stb.

Hasonlóan a gyro értékekre is.
Mutasd a teljes hozzászólást!

  • Mi a probléma a kapott/mért gyorsulás adatokkal?

    Gyorsulás alapján nem fog menni a pozíció számítás, amennyiben az volt az eredeti célod..
    Mutasd a teljes hozzászólást!
  • Az a probléma, hogy ha fixen tartom a szenzort, tehát nem forgatom, de mozgatom a térben, akkor mindenütt ugyan azt mutatja.. illetve bármekkora értéket el tudok érni bárhol a térben ezzel nem is lenne baj, de ha elfordítom, akkor egy fix számot mutat, és nem megy se fel, se le az értéke.

    Kicsit kifacsart magyarázat lett, de gondolom érthető mit szeretnék mondani :D

    Pár fórumon elvétve olvastam olyat, hogy valahogy meg lehet oldani, de bonyolult... etc. de legtöbb helyen azt írták, hogy nem lehet megoldani, vagy nem is volt szó róla, csak yaw pitch és roll adatokat használtak DMP-vel.

    Józan parasztésszel én meg azt hittem, hogy ez így működhet. Úgy szerettem volna, hogy az elmozdulást egy változóból kivonni/hozzáadni és egy relatív pozíciót szerezni ezáltal, ez sem megoldható?
    Mutasd a teljes hozzászólást!
  • Kicsit kifacsart magyarázat lett, de gondolom érthető mit szeretnék mondani

    Hát számomra nem igazán :)

    Úgy szerettem volna, hogy az elmozdulást egy változóból kivonni/hozzáadni és egy relatív pozíciót szerezni ezáltal, ez sem megoldható?

    Megoldható, csak a hibák összeadódnak és nagyon hamar nagyon pontatlan értékeket fogsz kapni. (kettős integrálás..)
    Mutasd a teljes hozzászólást!
  • Hogy ha mozgatom a szenzort.. a saját tengelye körül, akkor változnak az értékek, de ez teljesen független attól, ha egy vektor irányába eltolom abban a helyzetben, amiben tartottam, nem változik egy érték sem, és én úgy gondoltam, hogy az eltolás sebességének változását méri, és azt majd én úgy szépen megkapom raw datában.

    Hogy lehetne akkor ezen az értéken pontosítani, vagy ez a módszer teljesen kuka? A FilterPy library sem segíthet? és ha ez így használhatatlan, tudnál tanácsot adni hogy mivel kéne ennek nekikezdeni?

    Illetve ezt a pontatlan számítást sem tudom, hogyan kell ezekből az adatokból egyáltalán elkezdeni. Itt akadtam el... Próbálkoztam valamivel, de azzal nem sokra mentem :D vagy "csak" kettős integrálás, és utána a kapott értékkel már így dolgozhatnék a pontatlan értéket megkapva ahogy leírtam?

    X:  -397.7 Y:  -671.6 Z:  1557.9
    X:  -311.3 Y:  -746.0 Z:  1481.1
    X:  -272.1 Y:  -617.2 Z:  1639.9
    X:  -286.1 Y:  -756.8 Z:  1079.9
    X:  -262.1 Y:  -661.2 Z:  1705.5
    X:  -290.9 Y:  -397.6 Z:  1564.7
    X:  -264.1 Y:  -404.8 Z:  1653.1
    X:  -238.5 Y:  -462.8 Z:  1754.3
    X:  -222.5 Y:  -167.6 Z:  1676.7
    X:  -171.7 Y:  -194.8 Z:  1819.5
    X:  -154.1 Y:  -245.6 Z:  1632.7
    X:  -88.1 Y:  -217.2 Z:  1771.5
    X:  -46.9 Y:  -138.4 Z:  1699.9
    X:  100.3 Y:  -36.4 Z:  1679.1
    X:  80.7 Y:  137.6 Z:  1645.9
    X:  163.1 Y:  124.8 Z:  1719.9
    X:  212.3 Y:  184.0 Z:  1810.3
    X:  303.5 Y:  354.0 Z:  1595.5
    X:  400.3 Y:  214.4 Z:  1565.5
    X:  519.9 Y:  285.2 Z:  1504.3
    X:  648.7 Y:  302.8 Z:  1374.7
    X:  707.9 Y:  258.4 Z:  1320.7
    X:  713.9 Y:  4.0 Z:  1589.5
    X:  820.7 Y:  348.4 Z:  1281.1
    X:  867.9 Y:  174.4 Z:  1307.1
    X:  960.7 Y:  219.6 Z:  1161.1
    X:  989.5 Y:  193.2 Z:  1236.3
    Mutasd a teljes hozzászólást!
  • Pont arra van a kalman-filter, hogy a gps, imu, akármi összeszemetelt adathalmazából számít tisztított és közelítő értékeket, amit aztán föl lehet használni tényleges számolásokra.
    Mutasd a teljes hozzászólást!
  • Most utána néztem, találtam egy SciPy nevezetű libraryt ami tud kettős integrálást, a kalman filterrel nem tudnád leírni pár lépésben hogy mégis mit kéne kezdeni ezekkel az adatokkal, vagy ez mitől függ? Ahogy a FilterPy dokumentációjában is olvastam, kalman-filterből is egy tucat van, azt sem tudom melyiket kéne használni... Nagyon szeretném megcsinálni ezt a dobot, nem tudnátok segíteni a számításokban? Legalább egy vázlattal. Sajnos nem értek hozzá. Vagy ez innentől kezdve hogy nem értem, elbukott?
    Mutasd a teljes hozzászólást!
  • Milyen platform, milyen oprendszer (ha van egyáltalán), milyen nyelv?
    Mutasd a teljes hozzászólást!
  • Arduino Uno
    Mega328P
    --------------------
    Intel i7 4720HQ

    (uname -a)
    4.8.0-41-generic #44~16.04.1-Ubuntu SMP Fri Mar 3 17:11:16 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

    (lsb_release -d)
    Ubuntu 16.04.2 LTS

    Python 2.7.12
    Mutasd a teljes hozzászólást!
  • ...az én elgondolásom szerint egy gyorsulásmérő az adott tengelyen lévő sebesség változást méri, de annak nulla közeli értéknek kéne lennie bármilyen helyzetben, ha nem mozog a szenzor.

    Nem. A gyorsulásmérő egy vektort ad vissza, mértékegysége m/sec^2. Ha nyugalmi állapotban kiszámítod a vektor hosszát 9.81 m/sec^2-et kell kapnod - a vektor irányítása pedig mutatja, hogy merre van a föld.
    A gyroscope pedig az adott tengely körüli elfordulás szögsebességét adja meg, mértékegysége: rad/sec.

    Az adatlapból idézve:

    The MPU-60X0 is the world’s first integrated 6-axis MotionTracking device that combines a 3-axis gyroscope, 3-axis accelerometer

    A felsorolt adatpárok gyroscope vagy accelerometer adatok?
    Nekem az se tiszta, hogy mit szeretnél elérni!? Hogy néz ki egy virtuális dob?
    Mutasd a teljes hozzászólást!
  • Azok gyorsulásmérő adatok, csak felszoroztam hogy jobban lássam a változást, 100.000-el

    Olyat szeretnék, mint pl az Aerodrum, vagyis hasonlót.

    3 dimenzióban meglennének a dob koordinátái, mettől meddig tart egy, egyelőre még csak egy téglatestet formázva, és ha az ütő azon területen belülre kerül, akkor a sebességének megfelelő hangerővel megszólaltat egy wav filet amit hozzá lehet rendelni. és ilyen dobokból épülne fel a szett.

    2 ütő(tamok, rideok, crashek), 2 lábdob, lábcin(váltogatva mert csak két lábam van).

    a pozíciószámítást pedig úgy gondoltam, hogy bekapcsolás után consoleba jelezné hogy tartsam mellkas magasságba az ütőt, majd innen kezdené számolni az elmozdulásokat.
    Mutasd a teljes hozzászólást!
  • Nézd át a hardware-ed specifikációját és akkor jobban fogod látni a helyzetet. Szerintem más adatokat vársz a szenzoroktól, mint amit valójában szolgáltatnak..
    Mutasd a teljes hozzászólást!
  • Szia!

    Jó ötlet a specifikáció mert mintha azt olvastam volna (2 perc kereséssel együtt), hogy az adatokat fel is tudja dolgozni a benne lévő cél processzor, de tévedhetek is.

    Kérdezőnek:

    Korábban tárgyaltuk azt, hogy a szenzort kalibrálni kell, majd a shift értékeket meg kell adni neki. A kódodban nem látom ezt, mert ez csak egy nyers kiolvasás példakód. Mi lett vele? Nem jó? Nem kell?
    Mutasd a teljes hozzászólást!
  • A beépített feldolgozóval az volt a baj, hogy csak yaw pitch és roll értékeket ad vissza, és ahogy láttam azt drónok szintezéséhez használják, és az nem volt jó, mert csak az orientációját adja meg tudomásom szerint. Másodjára a raw adatokat próbáltam, itt ragadtam le az adatok használhatóvá tételénél. Egyelőre nem a szűréssel és nem a pontatlansággal van a bajom (bár később lehet az is baj lenne ezért be is állítottam pythonban, kicsit eltolódott jobbra a példakód ábráján), hanem azzal hogy semmiféle értelmes számítást sem tudok vele végezni, mert olyan adatokat kapok a szenzorból, amikre nem számítottam.. de valahogy meg lehet oldani a relatív pozíció számítását, és ezt filterezéssel kombinálva csak használható lenne valamilyen mértékben az adat. Azt szeretném megtudni, hogy ebből a nyers adatból hogyan tudom kiszámítani a relatív pozíciót.
    Mutasd a teljes hozzászólást!
  • Ez nem feltétlen programzási feladat lesz elsőre, szerintem gyere át a hobbielektronika oldalra, ott van Arduino topic.

    Elsőre több észrevételem is van. A szenzor visszaad neked valami értéket, de egyelőre nem tudni, hogy az milyen skálán mozog. Nem mindegy, hogy a szenzor érzékenysége 2,4,8,16 g
    -re van állítva, valamint az sem mindegy, hogy az adott szenzor milyen típusú számot ad vissza, de az most mindegy.

    Innen példa:

    How to read a gyro/accelerometer




    Ha pl 2g-re van beállítva és a mért adat 1944, akkor pl ax=(1944/16384)*9,81

    stb.

    Hasonlóan a gyro értékekre is.
    Mutasd a teljes hozzászólást!
  • A másik észrevételem pedig az lett volna, hogy nem mindegy, az MSB/LSB bit sem. ki kell deríteni, hogy a szenzor által szolgáltatott adat byte sorrendje megegyezik-e a feldolgozás során használttal.

    Ilyen azért van, mert ezeket a szenzorokat tudni kell használni mindkét rendszerben.
    Mutasd a teljes hozzászólást!
  • Ezer köszi! Erről nem is tudtam, akkor átnézek oda is :D
    Mutasd a teljes hozzászólást!
  • Ezek mind olyan dolgok, amiket a gyártó pontosan lespecifikál és dokumentál számodra. (Az az ő érdeke, hogy te tudd használni a termékét).
    Akár programozol és egy új könyvtárral kezdesz foglalkozni, akár HW-el foglalkozol és veszel egy kütyüt, még mielőtt egy sor kódot írsz/megveszed a HW-t érdemes belenézni a rendelkezésre álló dokumentumokra, hogy valóban arra van-e szükséged..
    HW-re meg végképp igaz, hiszen a lábkiosztás sem vele született/elsajátítható tudás, ki kell nyitni a specifikációt és pontosan megnézni, hogy hol és mit csinál. Vakvilágba nekiállva káosz lesz a vége.. Kicsit több és mélyebb tervezés segíthet :)
    Mutasd a teljes hozzászólást!
abcd