Operácie

Akcelerometre

Z SensorWiki

Modifikované cvičenie na DOMA:


Úloha: Akcelerometre ktoré máte v mobile, alebo ako samostatný senzor, použijeme na ovládanie 3D modelu v prostredí Processing.


Postup:

  1. Údaje z akcelerometrov v mobile prenesiete cez Bluetooth alebo cez WiFi pomocou niektorej z aplikácií, ktoré poznáte z predošlých cvičení. Kontrola: v programe Terminal.exe alebo podobnom skontrolujete, či prijímate správne údaje.
  2. Údaje prijmete v aplikácii, ktorú máte ako vzor uvedenú nižšie. Treba len:
    1. rozparsovať prijímané dáta na tri súradnice ax, ay a az.
    2. prepočítať zrýchlenia na natočenia roll, yaw a pitch.
    3. na základe výpočtu pohybovať objektom v okne
  3. Okrem vzorovej kocky, ktorú máte vo vzorovej aplikácii, vytvorte alebo stiahnite z internetu iný 3D model vo formáte .obj a demonštrujte na krátkom videu, že ním viete otáčať.


Odovzdať treba:

  • video na ktorom vidno ako otáčate objektom pohybom mobilu
  • zdrojový kód v Processingu (.pde)
  • model objektu (.obj)


Vzorový program

import processing.serial.*;

Serial myPort;
PShape myObject;

float yaw = 0.0;
float pitch = 0.0;
float roll = 0.0;

void setup()
{
  size(600, 600, P3D);

  // myObject = loadShape("tinker.obj");  // objekt, ktorym chcem hybat

  /* Toto je niekolko prikladov, ako si vybrat seriovy port, nie je aktivne
     ani jedno, musite si niektoru moznost odkomentovat                    */

  // ak nic neviete, vypiste si najprv vsetky porty co mate:
  printArray(Serial.list());
  
  // ak mate len jeden port, alebo viete ktory v poradi je ten vas:
  // myPort = new Serial(this, Serial.list()[1], 115200); 

  // ak viete cislo portu:
  //myPort = new Serial(this, "COM5:", 9600);        // Windows "COM#:"
  // myPort = new Serial(this, "\\\\.\\COM39", 115200); // Windows, od COM10 vyssie
  //myPort = new Serial(this, "/dev/ttyACM0", 9600);   // Linux "/dev/ttyACM#"
  //myPort = new Serial(this, "/dev/cu.usbmodem1217321", 9600);  // Mac "/dev/cu.usbmodem######"
}

void draw()
{
  serialEvent();   // nacitaj hodnoty z prichadzajucej spravy
  background(255); // biele pozadie
  lights();        // osvetlenie sceny

  translate(width/2, height/2); // pociatok suradnic bude v strede okna

    rotateX(radians(roll));
    rotateY(radians(-pitch));
    rotateZ(radians(yaw));

    drawObject();  // objekt bud nakreslime, alebo
    // shape(myObject); // zobrazime 3D model .obj


  // Ziskane hodnoty si pre istotu vypiseme aj do konzoly
  print(roll);
  print("\t");
  print(-pitch);
  print("\t");
  print(yaw);
  println();
}


void serialEvent()
{
  float aX, aY, aZ;
  int newLine = 13; // new line character in ASCII
  String message;

  do {
    message = myPort.readStringUntil(newLine);     // read from port until new line
    if (message != null) {
      String[] list = split(trim(message), " ");   // hodnoty su oddelene medzerami (ale mozem sem dat napr. ciarky)
      if (list.length >= 4 && list[0].equals("Orientation:")) {  // tu vyhodime zo zaciatku slovo Orientation: ale nemusi to byt vobec
        aX = float(list[1]); // convert to float yaw
        aY = float(list[2]); // convert to float pitch
        aZ = float(list[3]); // convert to float roll
        
        /* Tuto treba dopisat prevod zrychlenia v jednotlivych osiach na natocenia */ 
        /* Vasa uloha je namiesto pevnej hodnoty vlozit vypocet                    */

        yaw=45;
        pitch=-45;
        roll=45;        
        
      }
    }
  } while (message != null);
}


void drawObject()
{
  stroke(0); // black outline
  fill(255, 215, 0); // gold color
  box(100,100, 100); // cube

}

Tipy:

Ale predpokladám, že vám bude stačiť toto, kde G sú jednotlivé zrýchlenia a ϕ = roll and θ = pitch:


\tan \phi_{xyz} = \frac{G_{py}}{G_{pz}}


\tan \theta_{xyz} = \frac{-G_{px}}{G_{py}\sin \phi + G_{pz}\cos \phi} = \frac{-G_{px}}{\sqrt{G_{py}^2 + G_{pz}^2}}

Implementácia by mohla vyzerať napríklad takto (výsledky v radiánoch, potrebujeme potom stupne)

roll = atan2(accelerationY, accelerationZ);

pitch = atan2(-accelerationX, sqrt(accelerationY*accelerationY + accelerationZ*accelerationZ));

yaw =  atan2(accelerationZ/sqrt(accelerationX*accelerationX + accelerationZ*accelerationZ));




Návrat na zoznam cvičení...