1


我一直在玩一个带有 3 轴的加速度计:X、Y 和 Z。它在供应商的网站上说它测量重力。

我将这些数据发送到搅拌机游戏引擎,根据来自加速度计的数据值实时旋转立方体。但是,通过的值似乎不匹配。

在每个轴上,加速度计会在每个轴上输出 -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(matrix) 来影响立方体的旋转。但是我目前正在将错误的值投入矩阵 reorient() 函数

4

2 回答 2

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);他们给出了一些转换矩阵。看起来您的加速度计数据也受到了不足的约束(您还需要一个约束,指定围绕“向下”方向的旋转 - 可能是某种惯性“与先前位置的最小距离”计算?)

Edit3:有一个示例脚本可能会有所帮助;在我的机器上,它位于 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()
于 2011-03-24T15:13:03.697 回答
1

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

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

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

所以我们需要决定如何处理af。一个常见的做法是:如果N主要指向原始的 'Z' 轴,则使矩阵的新 'Y' 轴部分为M = N cross X

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

归一化M然后找到矩阵的“X”轴部分:L = M cross N。标准化L

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


编辑:

所以我们有了三个加速度计值:Ax、Ay、Az 第一步是对它们进行归一化:

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-axis,那么我们想要形成一个矩阵,该矩阵将旋转立方体的 z 轴,使其与N对齐。

于 2011-03-24T17:24:12.983 回答