EDIT мне нужно пересмотреть этот вопрос. Некоторые ошибки были сделаны
Ваш датчик в порядке.
Ну, записи вектора вращения не могут быть просто связаны с углом поворота вокруг определенной оси. Структура SensorEvent представляет собой временную метку, датчик, точность и значения. В зависимости от вектора float [] values
различаются размером 1-5.
Значения векторов вращения основаны на единичных кватернионах, вместе образуя вектор, представляющий ориентацию этого мирового кадра относительно вашего фиксированного кадра смартфона выше
Они единичны и положительны против часовой стрелки.
Ориентация телефона представлена поворотом, необходимым для согласования координат «Восток-Север-Вверх» с координатами телефона. То есть, применение вращения к мировому кадру (X, Y, Z) приведет к их согласованию с координатами телефона (x, y, z).
Если вектор будет Rotation-Matrix можно написать как
v_body = R_rot_vec * v_world (<--)
толкая мировой вектор в смартфон фиксируется описание.
Кроме того о векторе:
Три элемента вектора вращения равны последних трех компонентов блока кватернионов < сов (θ/2), х грех (θ/2), y sin (θ/2), z * sin (θ/2)>.
Q: Так что с ним делать?
В зависимости от вашего соглашения с Эйлером (возможно, 24 последовательности, действительные 12 единиц) вы можете рассчитать соответствующие углы u: = [ψ, θ, φ], например.применяя
последовательность:

Если у вас уже есть матричные элементы вращения получают Euler следующим образом:
последовательности :
с 1-3 кварталов всегда будучи values[0-2]
(Не путайте u_ijk
как ref (Diebel) использует различные соглашения, соответствующие стандарту)
Но подождите, ваша связанная таблица имеет только 3 значения, что аналогично к тому, что я получаю. Это один SensorEvent
шахты, последние три печатаются из values[]
23191581386897 11 -75 -0,0036907701 -0.014922042 0,9932963 метку времени sensortype значения точности [0] значения [1] значения [2] 4Q-3values = 1q Unkown. Первый q0 является дополнительной информацией (также doku говорит, что он должен быть там под values[3]
, зависит от вашего уровня API). Поэтому мы можем использовать норму (= длину) для вычисления q0 из трех других.

Задайте уравнение || q || = 1 и решить для q0. Теперь все q0-3 известны.
Кроме того мой андроид 4.4.2 не имеет четвертую оценочную заголовок Точности (в радианах) внутри value[4]
, поэтому я оцениваю event.accuracy
:
for (SensorEvent e : currentEvent) {
if (e != null) {
String toMsg = "";
for(int i = 0; i < e.values.length;i++) {
toMsg += " " + String.valueOf(e.values[i]);
}
iBinder.msgString(String.valueOf(e.timestamp) + " "+String.valueOf(e.sensor.getType()) + " " + String.valueOf(e.accuracy) + toMsg, 0);
}
}
Поместите эти уравнения в код, и вы получите вещи отсортированных.
Как я уже имел дело с преобразованием quat-> eul, я написал код Lite C++, преобразующий Quats. используя либо XYZ, либо ZYX. Если вам приходится сидеть перед «linux» -shell, вы можете использовать его как немного conversion helper или иначе просто посмотрите исходный код в папке. (BSD лицензией)
Соответствующая часть для XYZ
/*quaternation to euler in XYZ (seq:123)*/
double* quat2eulerxyz(double* q){
/*euler-angles*/
double psi = atan2(-2.*(q[2]*q[3] - q[0]*q[1]) , q[0]*q[0] - q[1]*q[1]- q[2]*q[2] + q[3]*q[3]);
double theta = asin(2.*(q[1]*q[3] + q[0]*q[2]));
double phi = atan2(2.*(-q[1]*q[2] + q[0]*q[3]) , q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3]);
/*save var. by simply pushing them back into the array and return*/
q[1] = psi;
q[2] = theta;
q[3] = phi;
return q;
}
Вот несколько примеров, применяющих четв к euls: 
Q: Что последовательность IJK стоять?
Возьмите два координатных кадра A и B, накладывающих друг на друга (все оси друг в друга) и начните вращать рамку B через ось i, имеющую угол psi
, тогда ось j имеет угол theta
и последнюю ось z, имеющую phi
. Он также может быть α, β, γ для i, j, k. Я не подбираю цифры, поскольку они запутывают (Diebel против других бумаг).
R(psi,theta,phi) = R_z(phi)R_y(theta)R_x(psi) (<--)
Хитрость элементарно севообороты применяются справа налево, хотя мы читаем последовательность слева направо. Таковы три элементарных поворотов вы собираетесь через идти от
A to B: *v_B = R(psi,theta,phi) v_A*
Q: Так как получить эйлеровых углов/четв перейти от [0 °, 0 °, 0 °], чтобы, например, , [0 °, 90 °, 0 °]?
Сначала выровняйте оба кадра с изображений, соответствующие известному кадру устройства B, к «невидимому» мировому кадру A.Ваш сделанный наложение, когда углы все доходят до [0 °, 0 °, 0 °]. Просто выясните, где находится север, юг и восток, где вы сидите прямо сейчас, и указывайте раму устройства B в эти направления. Теперь, когда вы вращаетесь вокруг оси Y против часовой стрелки на 90 °, при преобразовании кватерниона вы будете иметь желаемые значения [0 °, 90 °, 0 °].
Джулиан
* кинематика источник: Source Diebel(Stanford) с твердой информации на фоне механики (осторожно: для Diebel XYZ обозначается u_321 (1,2,3), а ZYX является u_123 (3,2,1)), и this - хорошая отправная точка.
Я также заметил, что документация не соответствует фактическому перемещению устройств. По-видимому, все устройства вращаются неправильно. –
Как вы получаете значения? Используя getOrientation? –
Я только что прошел через это видео: https://www.youtube.com/watch?v=C7JQ7Rpwn2k#t=2307, которые очень хорошо объясняют эти понятия. Тем более, вы, вероятно, не хотите использовать углы эйлеров, но вместо этого используйте матрицу вращения. – mbonnin