2016-03-18 15 views
1

丸いプレートが回転しているとき、回転角度(写真を参照)を見つける必要があります。 実際には、回転角は1つのみ必要ですが、Samsung Galaxy S4のSensors2OSCで取得したデータがあります。 このアプリを使用すると、加速度計とジャイロスコープの浮動小数点データをOSCで処理することができます。 Iは、センサ融合のために使用する必要がセンサ最も正確な結果を提供する方法 電話をプレートの背面に搭載されている..アンドロイド携帯からの生データを使った回転角度

https://github.com/SensorApps/Sensors2OSC

image


import oscP5.*; 
import netP5.*; 

OscP5 oscP5; 
NetAddress myRemoteLocation; 

LowPass lp; 
float number1 = 0.0; 

void setup() { 
    size(1200, 600, P3D); 
    oscP5 = new OscP5(this, 9000); 
    lp = new LowPass(10); //The argument is the FIFO queue length 
} 

void draw() { 
    background(0); 
    lights(); 

    pushMatrix(); 
    translate(300, height/2, -100); 
    rotateZ(-number1); 
    box(330, 200, 40); 
    popMatrix(); 

    pushMatrix(); 
    translate(900, height/2, -100); 
    lp.input(number1); 
    rotateZ(lp.output); 
    box(330, 200, 40); 
    popMatrix(); 
} 

/* incoming osc message are forwarded to the oscEvent method. */ 
void oscEvent(OscMessage theOscMessage) { 

    if (theOscMessage.addrPattern().equals("/rotationvector/z")); 
    number1 = theOscMessage.get(0).floatValue(); 
} 

class LowPass { 
    ArrayList buffer; 
    int len; 
    float output; 

    LowPass(int len) { 
    this.len = len; 
    buffer = new ArrayList(len); 
    for (int i = 0; i < len; i++) { 
     buffer.add(new Float(0.0)); 
    } 
    } 

    void input(float v) { 
    buffer.add(new Float(v)); 
    buffer.remove(0); 

    float sum = 0; 
    for (int i=0; i<buffer.size(); i++) { 
     Float fv = (Float)buffer.get(i); 
     sum += fv.floatValue(); 
    } 
    output = sum/buffer.size(); 
    } 
} 
+0

あなたの写真は直角を持っている必要があります –

答えて

-1

だけOrientationEventListenerオブジェクトをインスタンス化します。 onOrientationChangedメソッドは回転角度を与えます。

1

あなたは、電話機自体からセンサーの値を取得する方法を聞いていないようですね。センサ値はすでにSensors2OSCから取得されています。この値はOSC経由の処理に送信されています。あなたはおそらくoscP5のようなものを使用しています。

処理スケッチに入ってくるメッセージを解析して、処理コードのセンサー値にアクセスできるようにしてから、これらのセンサー値を角度に変換する方法を尋ねると思います。

ステップ1は、OSC経由のメッセージを取得することです。あなたはhereの例を見つけることができ、関心のある機能はoscEvent(OscMessage theOscMessage)の機能です。

この作業が完了したら、の手順2は、メッセージを渡すデータを解析することです。 the OscMessage documentationに便利な機能のリストがあります。 3が、その後の角度にそれらの生の加速度値を変換することである

void oscEvent(OscMessage theOscMessage) { 
    float xAccel = //parse theOscMessage to get X accelerometer reading 
    float yAccel = //parse theOscMessage to get Y accelerometer reading 
    float zAccel = //parse theOscMessage to get Z accelerometer reading 

    println(xAccel + ", " + yAccel + ", " + zAccel); 
} 

ステップ:あなたの最終目標は、このようなものを持っていることです。 "角度にアンドロイド加速度計を" グーグルことを含め、結果のトンを返します。

あなたの目標は、このような何かを持っていることです。

void oscEvent(OscMessage theOscMessage) { 
    float xAccel = //parse theOscMessage to get X accelerometer reading 
    float yAccel = //parse theOscMessage to get Y accelerometer reading 
    float zAccel = //parse theOscMessage to get Z accelerometer reading 

    float angle = //calculate angle 
    println(angle); 
} 

そこから、角度の値で何でもできます。 Androidアプリがすべての加速度計の値を1つのメッセージで送信するのか、複数のメッセージに分割するのかはわからないので、それよりも少し複雑かもしれません。あなたはメッセージが何を含んでいるかを本当に理解するまで遊ばなければなりません。ここ

+0

私の問題は、処理側で適切なセンサーフュージョンを選択することです。角度を正確に測定するためにデータを操作する最良の方法は何でしょうか?加速度センサーが単独で使用した場合、非常に正確なデータを提供していません。 – potter3366

+0

@ potter3366私はそれを理解しています。私があなたに与えた4つのリンクとGoogle検索をチェックしてください。 –

+0

仮想センサー回転ベクトルが最良の結果をもたらすようです。今度はこれらの値を対応する角度に変換しなければなりません。 – potter3366

1
import oscP5.*; 
import netP5.*; 
import toxi.geom.*; 

OscP5 oscP5; 
NetAddress myRemoteLocation; 

float number0 = 0.0; 
float number1 = 0.0; 
float number2 = 0.0; 
float number3 = 0.0; 

float[] axis = new float[3]; 
Quaternion quat = new Quaternion(1, 0, 0, 0); 

void setup() { 
    size(1200, 600, P3D); 
    oscP5 = new OscP5(this, 9000); 
} 

void draw() { 
    background(0); 
    lights(); 

    quat.set(number0, number1, number2, number3); 
    axis = quat.toAxisAngle(); 

    pushMatrix(); 
    translate(width/2, height/2, -100); 
    rotate(axis[0], axis[1], axis[2], axis[3]); 
    box(330, 200, 40); 
    popMatrix(); 
} 

/* incoming osc message are forwarded to the oscEvent method. */ 
void oscEvent(OscMessage theOscMessage) { 

    if (theOscMessage.addrPattern().equals("/rotationvector/X")) 
    number1 = theOscMessage.get(0).floatValue(); 
    if (theOscMessage.addrPattern().equals("/rotationvector/Y")) 
    number2 = theOscMessage.get(0).floatValue(); 
    if (theOscMessage.addrPattern().equals("/rotationvector/Z")) 
    number3 = theOscMessage.get(0).floatValue(); 
    if (theOscMessage.addrPattern().equals("/rotationvector/cos")) 
    number0 = theOscMessage.get(0).floatValue(); 
} 
+0

私はtoxiclibsを使って四元数(回転ベクトル)を:ラジアンでの回転角度、回転軸x、y、zからなるフロート配列に変換しました。改善... – potter3366

1

のみつのセンサを含む溶液である - 加速度計+ローパスフィルタ

TODO:+カルマン又は補色フィルタを加速度計とジャイロスコープのデータを組み合わせる

ジャイロオフセット値を知ることが必要ですコンプリメンタリフィルタを実装するためのジャイロ感度。三星銀河のこの値はどこで見つけることができますか?

処理中にオフラインでこれらのデータを処理し、正確な方向を取得するいくつかの機能は、すでに(例えばSensorManager.getRotationMatrixなど)アンドロイドに実装されている処理で実装する必要があるため、ハード..です

http://plaw.info/2012/03/android-sensor-fusion-tutorial/

import oscP5.*; 
import netP5.*; 

OscP5 oscP5; 
NetAddress myRemoteLocation; 

float number1, number1a; 
float number2, number2a; 
float number3, number3a; 
float r, b; 
float x1, y1, x2, y2, cx, cy, a1, b1; 
int rec1x = 150, rec1y = 150; 

LowPass lp; 

void setup() { 
    size(550, 550); 
    lp = new LowPass(10); 
    oscP5 = new OscP5(this, 9000); 
} 

void draw() { 
    background(50); 

    b = number2/sqrt(number1 * number1 + number3 * number3); 
    r = atan(b); 

    //accelerometer 
    noStroke(); 
    fill(50, 20, 200, 80); 
    rect(rec1x, rec1y, 250, 250); 
    fill(0); 
    ellipse(rec1x + (250/2), rec1y + (250/2), 240, 240); 

    //acc_line 
    cx = rec1x + (250/2); 
    cy = rec1y + (250/2); 
    lp.input(r); 
    a1 = 120 * cos(lp.output); 
    b1 = 120 * sin(lp.output); 
    x1 = cx - a1; 
    y1 = cy - b1; 
    x2 = cx + a1; 
    y2 = cy + b1; 
    stroke(2, 2, 255); 
    strokeWeight(3); 
    line(x1, y1, x2, y2); 
} 

/* incoming osc message are forwarded to the oscEvent method. */ 
void oscEvent(OscMessage theOscMessage) { 

    if (theOscMessage.addrPattern().equals("/accelerometer/X")) 
    //if (theOscMessage.addrPattern().equals("/linearacceleration/X")) 
    number1 = theOscMessage.get(0).floatValue(); 
    if (theOscMessage.addrPattern().equals("/accelerometer/Y")) 
    //if (theOscMessage.addrPattern().equals("/linearacceleration/Y")) 
    number2 = theOscMessage.get(0).floatValue(); 
    if (theOscMessage.addrPattern().equals("/accelerometer/Z")) 
    //if (theOscMessage.addrPattern().equals("/linearacceleration/Z")) 
    number3= theOscMessage.get(0).floatValue(); 
    if (theOscMessage.addrPattern().equals("/gyroscope/X")) 
    number1a = theOscMessage.get(0).floatValue(); 
    if (theOscMessage.addrPattern().equals("/gyroscope/Y")) 
    number2a = theOscMessage.get(0).floatValue(); 
    if (theOscMessage.addrPattern().equals("/gyroscope/Z")) 
    number3a = theOscMessage.get(0).floatValue(); 
} 

class LowPass { 
    ArrayList buffer; 
    int len; 
    float output; 

    LowPass(int len) { 
    this.len = len; 
    buffer = new ArrayList(len); 
    for (int i = 0; i < len; i++) { 
     buffer.add(new Float(0.0)); 
    } 
    } 

    void input(float v) { 
    buffer.add(new Float(v)); 
    buffer.remove(0); 

    float sum = 0; 
    for (int i=0; i<buffer.size(); i++) { 
     Float fv = (Float)buffer.get(i); 
     sum += fv.floatValue(); 
    } 
    output = sum/buffer.size(); 
    } 
} 
関連する問題