首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用android手机原始数据的旋转角度

使用android手机原始数据的旋转角度
EN

Stack Overflow用户
提问于 2016-03-18 23:10:45
回答 4查看 1.4K关注 0票数 0

当圆板转动时,我需要找到旋转的角度(请看图)。我实际上只需要一个旋转角度,但通过Sensors2OSC从三星银河S4获得的数据。这个应用程序使我能够接收加速度计和陀螺仪浮点数据处理通过OSC。手机安装在盘子的背面。

https://github.com/SensorApps/Sensors2OSC

哪种方法提供了最精确的结果,我要用哪些传感器进行传感器融合?

代码语言:javascript
复制
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();
  }
}
EN

回答 4

Stack Overflow用户

发布于 2016-03-19 13:09:23

听起来你不是在问如何从手机本身获取传感器值。您已经从Sensors2OSC获得了传感器值,它将它们发送到OSC上进行处理。您可能正在使用类似于oscP5的东西。

我想您是在问如何解析处理草图中的消息,以便访问处理代码中的传感器值,然后如何将这些传感器值转换成一个角度。

步骤1是通过OSC获取消息。您可以找到一个示例这里,您关心的函数是oscEvent(OscMessage theOscMessage)函数。

一旦完成了这个任务,步骤2就是解析来自消息的数据。您可以查看OscMessage文档以获得可能有用的函数列表。你的最终目标是拥有这样的东西:

代码语言:javascript
复制
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);
}

步骤3然后将这些原始加速度计的值转换成一个角度。谷歌搜索"android加速度计到角度“会得到大量的结果,包括:

你的目标是拥有这样的东西:

代码语言:javascript
复制
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应用程序是否会在一条消息中发送所有的加速度计值,或者它是否会被分成多个消息。在你真正理解这些信息的含义之前,你将不得不四处游玩。

票数 0
EN

Stack Overflow用户

发布于 2016-03-19 15:48:45

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2016-03-20 00:23:59

这里的解决方案只有一个传感器-加速度计+低通滤波器。

TODO:将加速度计和陀螺仪数据+ Kalman或互补滤波器组合在一起

为了实现互补滤波,需要了解陀螺的偏移值和陀螺的灵敏度。在哪里我可以找到三星银河的这些价值?

在处理过程中离线处理这些数据并获得精确的定位是很困难的,因为在处理过程中需要实现一些已经在android (如SensorManager.getRotationMatrix)中实现的功能。

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

代码语言:javascript
复制
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();
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36095767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档