当圆板转动时,我需要找到旋转的角度(请看图)。我实际上只需要一个旋转角度,但通过Sensors2OSC从三星银河S4获得的数据。这个应用程序使我能够接收加速度计和陀螺仪浮点数据处理通过OSC。手机安装在盘子的背面。
https://github.com/SensorApps/Sensors2OSC
哪种方法提供了最精确的结果,我要用哪些传感器进行传感器融合?

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();
}
}发布于 2016-03-19 13:09:23
听起来你不是在问如何从手机本身获取传感器值。您已经从Sensors2OSC获得了传感器值,它将它们发送到OSC上进行处理。您可能正在使用类似于oscP5的东西。
我想您是在问如何解析处理草图中的消息,以便访问处理代码中的传感器值,然后如何将这些传感器值转换成一个角度。
步骤1是通过OSC获取消息。您可以找到一个示例这里,您关心的函数是oscEvent(OscMessage theOscMessage)函数。
一旦完成了这个任务,步骤2就是解析来自消息的数据。您可以查看OscMessage文档以获得可能有用的函数列表。你的最终目标是拥有这样的东西:
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加速度计到角度“会得到大量的结果,包括:
你的目标是拥有这样的东西:
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应用程序是否会在一条消息中发送所有的加速度计值,或者它是否会被分成多个消息。在你真正理解这些信息的含义之前,你将不得不四处游玩。
发布于 2016-03-19 15:48:45
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();
}发布于 2016-03-20 00:23:59
这里的解决方案只有一个传感器-加速度计+低通滤波器。
TODO:将加速度计和陀螺仪数据+ Kalman或互补滤波器组合在一起
为了实现互补滤波,需要了解陀螺的偏移值和陀螺的灵敏度。在哪里我可以找到三星银河的这些价值?
在处理过程中离线处理这些数据并获得精确的定位是很困难的,因为在处理过程中需要实现一些已经在android (如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();
}
}https://stackoverflow.com/questions/36095767
复制相似问题