将G Force数据转换为旋转?

时间:2011-03-24 14:48:12

标签: python math 3d accelerometer blender


我一直在玩带有3轴的加速度计:X,Y和Z.它在supplier's site上说它测量了引力。

我将此数据发送到搅拌机游戏引擎,我根据来自加速度计的数据值实时旋转多维数据集。然而,通过的价值似乎并不匹配。

在每个轴上,加速度计在每个轴上吐出-700到700的值,我需要将这些值转换为我可以在Blender中使用的值。我的数学知识还没有达到标准,所以我不知道从哪里开始。

如果有人能够对此有所了解,那就太棒了。

非常感谢 将

修改 目前我正在使用一些python代码将旋转值转换为矩阵:

def reorient(alpha, beta, gamma):
  a = math.cos(alpha) 
  b = math.sin(alpha) 
  c = math.cos(beta) 
  d = math.sin(beta) 
  e = math.cos(gamma) 
  f = math.sin(gamma)    
  ad = a*d 
  bd = b*d 
  matrix = [[c*e, -a*f+b*d*e, b*f+a*d*e], [c*f, a*e+b*d*f, -b*e+a*d*f], [-d, b*c, a*c]]
  return matrix 

然后我使用setOrientation(矩阵)来影响立方体的旋转。但是我目前正在将错误的值抛入矩阵reorient()函数

2 个答案:

答案 0 :(得分:1)

我猜你正在使用测量的加速度来找到引力方向(即向下)。如果您正在移动加速度计,除了转动它之外,还会有一些额外的力;想一想摆锤重量从它上面移动的加速度计,当你移动摆锤摆动时(虽然在这种情况下它会是一个非常短的,快速反应的摆锤?)。您可以尝试进行某种运动补偿,但尝试将传感器保持在固定位置可能更简单。

编辑:好吧,看起来我完全误读了这个问题 - 您想知道如何在脚本中进行轮换?

看起来每个Blender对象都有三个属性(.RotX,.RotY,.RotZ),它们包含当前值(以弧度表示)和一个执行旋转的方法(.rot(new_rotx,new_roty,new_rotz))请参阅http://www.blender.org/documentation/249PythonDoc/Object.Object-class.html处的文档。我目前正在研究如何应用旋转;更快。

Edit2:看起来角度被指定为欧拉角(http://en.wikipedia.org/wiki/Euler_angles);他们给出了一些转换矩阵。看起来你的加速度计数据还不够严格(你还需要一个约束,指定关于'向下'方向的旋转 - 可能是某种惯性'与先前位置的最小距离'计算?)

编辑3:有一个示例脚本可能会有所帮助;在我的机器上它位于C:\ Users \ Me \ AppData \ Roaming \ Blender Foundation \ Blender.blender \ scripts \ object_random_loc_sz_rot.py它显示了如何获取当前选定的对象并调整其旋转。希望有所帮助!

Edit4:为了便于讨论,这里有一些示例代码;它可能有点多余(我之前没有在Blender工作过)并且它不会解决问题,但它至少会为我们提供进一步讨论的共同基础; - )

#!BPY

"""
Name: 'Set rotation by accelerometer'
Blender: 249
Group: 'Object'
Tooltip: 'Set the selected objects rotation by accelerometer'
"""

__bpydoc__=\
'''
This script sets the selected objects rotation by accelerometer.
'''

from Blender import Draw, Scene
import math

def reorient(alpha, beta, gamma):
    a = math.cos(alpha)
    b = math.sin(alpha)
    c = math.cos(beta)
    d = math.sin(beta)
    e = math.cos(gamma)
    f = math.sin(gamma)

    ad = a*d
    bd = b*d

    return = [
        [c*e, -a*f+b*d*e, b*f+a*d*e],
        [c*f, a*e+b*d*f, -b*e+a*d*f],
        [-d,  b*c,        a*c      ]
    ]

def getAccel():
    # test stub -
    # need to get actual values from accelerometer here
    dx = -700
    dy = 100
    dz = 250
    return (dx,dy,dz)

def normalize(vec):
    "Return scaled unit vector"
    x,y,z = vec
    mag = (x*x + y*y + z*z)**0.5
    return (x/mag, y/mag, z/mag)

def main():
    scn = Scene.GetCurrent()
    try:
        obj = scn.objects.context
        euler = (obj.RotX, obj.RotY, obj.RotZ)
    except AttributeError:
        return

    down = normalize(getAccel())
    matrix = None
    # do something here to find new rotation-matrix
    #   based on euler and down
    # then

    if matrix:
        obj.setOrientation(matrix)
    else:
        # test value:
        # if reorient() is working properly, the
        # object's rotation should not change!
        obj.setOrientation(reorient(*euler))

if __name__=="__main__":
    main()

答案 1 :(得分:1)

假设您可以使用加速度计来正确确定哪种方式“向上”。我们可以将该向量称为 N 。在我看来,您希望立方体的“向上”方向与 N 对齐。如前所述,这使得立方体可以自由旋转,但你仍然可以找到一个可以完成你想要的旋转矩阵,但你需要考虑两个不同的情况,否则你将在解决方案中有一个奇点。我会假设立方体上的'Z'是'up'。

如果您将三个加速度计值视为矢量并将其标准化(以获得 N ),您将获得旋转矩阵的新“Z”轴部分,以便指向矢量z方向现在将与'向上'向量对齐。

| a d N.x |   |0|   |N.x|
| b e N.y | * |0| = |N.y|
| c f N.z |   |1|   |N.z|

所以我们需要决定如何处理a-f。一个常见的事情是:如果 N 主要指向原始的'Z'轴,那么使矩阵的新'Y'轴部分为 M = N 交叉 X

d =  0
e =  N.z
f = -N.y

归一化 M ,然后找到矩阵的'X'轴部分: L = M 交叉 N 。标准化 L

如果 N 大部分未指向“Z”轴(Nz <.707),那么您会发现新的“Y”轴部分为 M = N 交叉 Z 。归一化 M 并找到 L = M 交叉 N ,最后归一化 L


编辑:

所以我们有三个加速度计值:A.x,A.y,A.z。第一步是规范化它们:

a = sqrt(A.x*A.x + A.y*Ay + A.z*A.z);      and then 
N.x = A.x/a;  N.y = A.y/a;  N.z = A.z/a;

我们假设如果N == [0, 0, 1]那么正确的旋转矩阵就是单位矩阵。如果 N 没有直接指向 z轴,那么我们想要形成一个矩阵,它将旋转立方体的z轴,使其与ñ