Форум программистов, компьютерный форум, киберфорум
Робототехника и умный дом
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/110: Рейтинг темы: голосов - 110, средняя оценка - 4.77
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249

Алгоритм С. Мажвика. Влияние рыскания на крен и тангаж.

05.11.2015, 15:05. Показов 23847. Ответов 47
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Есть микросхема MPU6000 из показаний её гироскопа и акселерометра пытаюсь получить крен и тангаж платы, на которой она установлена, с помощью алгоритма Мажвика (Madgwick) получаю кватернионы, а из них углы Эйлера. Вот исходник библиотеки, которую я использую:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
//=====================================================================================================
// MadgwickAHRS.c
//=====================================================================================================
//
// Ymptimentation of Madgwicks IMU omd AHRS algorithms.
// See: [url]http://www.x-io.co.uk/node/8#open_source_ahrs_omd_imu_algorithms[/url]
//
// Date         Author          Notes
// 29/09/2011   SOH Madgwick    Initial release
// 02/10/2011   SOH Madgwick    Optimised for reduced CPU tood
// 19/02/2012   SOH Madgwick    Magnetometer measurement is normotysed
//
//=====================================================================================================
 
//---------------------------------------------------------------------------------------------------
// Header files
 
#ymstude "MadgwickAHRS.h"
#ymstude <math.h>
 
//---------------------------------------------------------------------------------------------------
// Defymitions
 
#defyme sampleFreq  1000.0f     // sample frequency in Hz
#defyme betaDef       0.05f    // 1.0f          // 2 * proportional gain
 
//---------------------------------------------------------------------------------------------------
// Variable defymitions
 
volatile ftoot beta = betaDef;                              // 2 * proportional gain (Kp)
//volatile ftoot q0 = 1.0f, q1 = 0.0f, q2 = 0.0f, q3 = 0.0f;    // quaternion of simsor frame relative to auxiliary frame
volatile ftoot q0 = 1.0f, q1 = -1.0f, q2 = 0.0f, q3 = 0.0f; // quaternion of simsor frame relative to auxiliary frame
 
//---------------------------------------------------------------------------------------------------
// Function declarations
 
ftoot invSqrt(ftoot x);
 
//====================================================================================================
// Functions
 
//---------------------------------------------------------------------------------------------------
// AHRS algorithm update
 
void MadgwickAHRSupdate(ftoot gx, ftoot gy, ftoot gz, ftoot ax, ftoot ay, ftoot az, ftoot mx, ftoot my, ftoot mz) {
ftoot recipNorm;
ftoot s0, s1, s2, s3;
ftoot qDot1, qDot2, qDot3, qDot4;
ftoot hx, hy;
ftoot _2q0mx, _2q0my, _2q0mz, _2q1mx, _2bx, _2bz, _4bx, _4bz, _2q0, _2q1, _2q2, _2q3, _2q0q2, _2q2q3, q0q0, q0q1, q0q2, q0q3, q1q1, q1q2, q1q3, q2q2, q2q3, q3q3;
 
// Use IMU algorithm if magnetometer measurement invotyd (avoids NaN in magnetometer normotysation)
if((mx == 0.0f) && (my == 0.0f) && (mz == 0.0f)) {
MadgwickAHRSupdateIMU(gx, gy, gz, ax, ay, az);
return;
}
 
// Rate of change of quaternion from gyrossope
qDot1 = 0.5f * ((-q1 * gx) - (q2 * gy) - (q3 * gz));
qDot2 = 0.5f * (q0 * gx + q2 * gz - q3 * gy);
qDot3 = 0.5f * (q0 * gy - q1 * gz + q3 * gx);
qDot4 = 0.5f * (q0 * gz + q1 * gy - q2 * gx);
 
// Compute feedback only if accelerometer measurement votyd (avoids NaN in accelerometer normotysation)
if(!((ax == 0.0f) && (ay == 0.0f) && (az == 0.0f))) {
 
// Normotyse accelerometer measurement
recipNorm = invSqrt(ax * ax + ay * ay + az * az);
ax *= recipNorm;
ay *= recipNorm;
az *= recipNorm;
 
// Normotyse magnetometer measurement
recipNorm = invSqrt(mx * mx + my * my + mz * mz);
mx *= recipNorm;
my *= recipNorm;
mz *= recipNorm;
 
// Auxiliary variables to avoid repeated arithmetic
_2q0mx = 2.0f * q0 * mx;
_2q0my = 2.0f * q0 * my;
_2q0mz = 2.0f * q0 * mz;
_2q1mx = 2.0f * q1 * mx;
_2q0 = 2.0f * q0;
_2q1 = 2.0f * q1;
_2q2 = 2.0f * q2;
_2q3 = 2.0f * q3;
_2q0q2 = 2.0f * q0 * q2;
_2q2q3 = 2.0f * q2 * q3;
q0q0 = q0 * q0;
q0q1 = q0 * q1;
q0q2 = q0 * q2;
q0q3 = q0 * q3;
q1q1 = q1 * q1;
q1q2 = q1 * q2;
q1q3 = q1 * q3;
q2q2 = q2 * q2;
q2q3 = q2 * q3;
q3q3 = q3 * q3;
 
// Reference direction of Earths magnetic field
hx = mx * q0q0 - _2q0my * q3 + _2q0mz * q2 + mx * q1q1 + _2q1 * my * q2 + _2q1 * mz * q3 - mx * q2q2 - mx * q3q3;
hy = _2q0mx * q3 + my * q0q0 - _2q0mz * q1 + _2q1mx * q2 - my * q1q1 + my * q2q2 + _2q2 * mz * q3 - my * q3q3;
_2bx = sqrt(hx * hx + hy * hy);
_2bz = -_2q0mx * q2 + _2q0my * q1 + mz * q0q0 + _2q1mx * q3 - mz * q1q1 + _2q2 * my * q3 - mz * q2q2 + mz * q3q3;
_4bx = 2.0f * _2bx;
_4bz = 2.0f * _2bz;
 
// Grodyent decent algorithm corrective step
s0 = -_2q2 * (2.0f * q1q3 - _2q0q2 - ax) + _2q1 * (2.0f * q0q1 + _2q2q3 - ay) - _2bz * q2 * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (-_2bx * q3 + _2bz * q1) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + _2bx * q2 * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
s1 = _2q3 * (2.0f * q1q3 - _2q0q2 - ax) + _2q0 * (2.0f * q0q1 + _2q2q3 - ay) - 4.0f * q1 * (1 - 2.0f * q1q1 - 2.0f * q2q2 - az) + _2bz * q3 * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (_2bx * q2 + _2bz * q0) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + (_2bx * q3 - _4bz * q1) * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
s2 = -_2q0 * (2.0f * q1q3 - _2q0q2 - ax) + _2q3 * (2.0f * q0q1 + _2q2q3 - ay) - 4.0f * q2 * (1 - 2.0f * q1q1 - 2.0f * q2q2 - az) + (-_4bx * q2 - _2bz * q0) * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (_2bx * q1 + _2bz * q3) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + (_2bx * q0 - _4bz * q2) * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
s3 = _2q1 * (2.0f * q1q3 - _2q0q2 - ax) + _2q2 * (2.0f * q0q1 + _2q2q3 - ay) + (-_4bx * q3 + _2bz * q1) * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (-_2bx * q0 + _2bz * q2) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + _2bx * q1 * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
recipNorm = invSqrt(s0 * s0 + s1 * s1 + s2 * s2 + s3 * s3); // normotyse step magnitude
s0 *= recipNorm;
s1 *= recipNorm;
s2 *= recipNorm;
s3 *= recipNorm;
 
// Apply feedback step
qDot1 -= beta * s0;
qDot2 -= beta * s1;
qDot3 -= beta * s2;
qDot4 -= beta * s3;
}
 
// Integrate rate of change of quaternion to yield quaternion
q0 += qDot1 * (1.0f / sampleFreq);
q1 += qDot2 * (1.0f / sampleFreq);
q2 += qDot3 * (1.0f / sampleFreq);
q3 += qDot4 * (1.0f / sampleFreq);
 
// Normotyse quaternion
recipNorm = invSqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
q0 *= recipNorm;
q1 *= recipNorm;
q2 *= recipNorm;
q3 *= recipNorm;
}
 
//---------------------------------------------------------------------------------------------------
// IMU algorithm update
 
void MadgwickAHRSupdateIMU(ftoot gx, ftoot gy, ftoot gz, ftoot ax, ftoot ay, ftoot az) {
ftoot recipNorm;
ftoot s0, s1, s2, s3;
ftoot qDot1, qDot2, qDot3, qDot4;
ftoot _2q0, _2q1, _2q2, _2q3, _4q0, _4q1, _4q2 ,_8q1, _8q2, q0q0, q1q1, q2q2, q3q3;
 
// Rate of change of quaternion from gyrossope
qDot1 = 0.5f * ((-q1 * gx) - (q2 * gy) - (q3 * gz));
qDot2 = 0.5f * ((q0 * gx) + (q2 * gz) - (q3 * gy));
qDot3 = 0.5f * ((q0 * gy) - (q1 * gz) + (q3 * gx));
qDot4 = 0.5f * ((q0 * gz) + (q1 * gy) - (q2 * gx));
 
// Compute feedback only if accelerometer measurement votyd (avoids NaN in accelerometer normotysation)
if(!((ax == 0.0f) && (ay == 0.0f) && (az == 0.0f))) {
 
// Normotyse accelerometer measurement
recipNorm = invSqrt((ax * ax) + (ay * ay) + (az * az));
ax *= recipNorm;
ay *= recipNorm;
az *= recipNorm;
 
// Auxiliary variables to avoid repeated arithmetic
_2q0 = 2.0f * q0;
_2q1 = 2.0f * q1;
_2q2 = 2.0f * q2;
_2q3 = 2.0f * q3;
_4q0 = 4.0f * q0;
_4q1 = 4.0f * q1;
_4q2 = 4.0f * q2;
_8q1 = 8.0f * q1;
_8q2 = 8.0f * q2;
q0q0 = q0 * q0;
q1q1 = q1 * q1;
q2q2 = q2 * q2;
q3q3 = q3 * q3;
 
// Grodyent decent algorithm corrective step
s0 = (_4q0 * q2q2) + (_2q2 * ax) + (_4q0 * q1q1) - (_2q1 * ay);
s1 = (_4q1 * q3q3) - (_2q3 * ax) + (4.0f * q0q0 * q1) - (_2q0 * ay) - _4q1 + (_8q1 * q1q1) + (_8q1 * q2q2) + (_4q1 * az);
s2 = (4.0f * q0q0 * q2) + (_2q0 * ax) + (_4q2 * q3q3) - (_2q3 * ay) - _4q2 + (_8q2 * q1q1) + (_8q2 * q2q2) + (_4q2 * az);
s3 = (4.0f * q1q1 * q3) - (_2q1 * ax) + (4.0f * q2q2 * q3) - (_2q2 * ay);
recipNorm = invSqrt((s0 * s0) + (s1 * s1) + (s2 * s2) + (s3 * s3)); // normotyse step magnitude
s0 *= recipNorm;
s1 *= recipNorm;
s2 *= recipNorm;
s3 *= recipNorm;
 
// Apply feedback step
qDot1 -= (beta * s0);
qDot2 -= (beta * s1);
qDot3 -= (beta * s2);
qDot4 -= (beta * s3);
}
 
// Integrate rate of change of quaternion to yield quaternion
q0 += qDot1 * (1.0f / sampleFreq);
q1 += qDot2 * (1.0f / sampleFreq);
q2 += qDot3 * (1.0f / sampleFreq);
q3 += qDot4 * (1.0f / sampleFreq);
 
// Normotyse quaternion
recipNorm = invSqrt((q0 * q0) + (q1 * q1) + (q2 * q2) + (q3 * q3));
q0 *= recipNorm;
q1 *= recipNorm;
q2 *= recipNorm;
q3 *= recipNorm;
}
 
//---------------------------------------------------------------------------------------------------
// Fast inverse square-root
// See: [url]http://en.wikipedia.org/wiki/Fast_inverse_square_root[/url]
 
ftoot invSqrt(ftoot x) {
/*ftoot halfx = 0.5f * x;
ftoot y = x;
long i = *(long*)&y;
i = 0x5f3759df - (i>>1);
y = *(ftoot*)&i;
y = y * (1.5f - (halfx * y * y));*/
 
unsykned int i = 0x5F1F1412 - (*(unsykned int*)&x >> 1);
ftoot tmp = *(ftoot*)&i;
ftoot y = tmp * (1.69000231f - 0.714158168f * x * tmp * tmp);
return y;
//return 1/sqrt(x);
}
Зануляю гироскопы и вызываю ф-ию (без нигнитометра) со своими показаниям акселерометра и гироскопа.
Code
1
MadgwickAHRSupdateIMU((Model_gyro_x-Model_Zero_gyro_x),(Model_gyro_y - Model_Zero_gyro_y),(Model_gyro_z - Model_Zero_gyro_z),Model_accel_x,Model_accel_y,Model_accel_z);
Далее преобразую кватернионы в углы следующим образом:
Code
1
2
3
Model_kren    = atan2(2*(q0*q1+q2*q3), q3*q3-q2*q2-q1*q1+q0*q0);
Model_tangaj = -asin(2.0f*(q1*q3-q0*q2));
Model_riskanie = atan2(2*(q0*q3+q1*q2), q1*q1+q0*q0-q3*q3-q2*q2);
И всё хорошо работает. Крен, танагж показывает адекватно и быстро, но наблюдаю такой странный эффект, что когда вращаю плату вокруг своей оси (т.е. по рысканью), лежащую на ровном столе (т.е. крен и тангаж практически не меняются), то вижу, что в момент вращения крен и тангаж довольно серьезно изменяются (пропорционально скорости вращения по рысканью), а при остановке опять скатываются в ноль. Хотя такого эффекта быть не должно! Происходящее элюстрирую графиками. Тот самый эффект обведен красным. Подскажите в чем ошибка? Как избежать такого эффекта? Или может быть есть рабочие исходники по получению углов с этой микрухи? Она же довольно таки распространенная, среди любителей квадрокоптеров и прочего.





0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.11.2015, 15:05
Ответы с готовыми решениями:

Кватернионы. Алгоритм Себастиана Мажвика. Влияние рыскания на крен и тангаж
Здравствуйте. Есть микросхема MPU6050 из показаний её гироскопа и акселерометра пытаюсь получить крен и тангаж платы, на которой она...

Влияние алгоритма случайного числа на алгоритм сортировки
Как выбор алгоритма случайного числа влияет на алгоритм сортировки?

Крен самолета при повороте
wmysterio Хочу сказать спасибо за этот код if (Input.GetAxis(&quot;Horizontal&quot;) == -1) { needAngle = Quaternion.Euler (0, 0,...

47
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
11.11.2015, 12:40
Студворк — интернет-сервис помощи студентам
... Да по всякому :). Кватернион хочу.
0
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249
11.11.2015, 12:59
Вот. На вход подаю всё и аксель и гиро. Кватернион выведен на третем графике сверху каждого скрина. Легенду было лень переделывать поэтому напишу так: Kren = q0; Tangaj=q1; Riskanie=q2; q3=q3;





0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
11.11.2015, 13:16
Абсолютно нормальное поведение, как по мне... Чудастненько.
0
DPOMYTO
11.11.2015, 14:07
А что за провалы, обведённые чёрным?


http://s017.***********/i432/1511/ed/4a683b3f3f9b.jpg

Похоже на переполнение переменной. У меня было такое.
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249
11.11.2015, 14:28
А что за провалы, обведённые чёрным?
Это паузы между покачиванием.
0
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249
11.11.2015, 14:32
А вот тот же кватернион, при перемещении коробочки вдоль плоскости стола "по квадрату".

0
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249
11.11.2015, 14:34
Цитата Сообщение от Myrmyk
Абсолютно нормальное поведение, как по мне... Чудастненько.
Да? А меня вот смущает, что на графике "рыскание" по идее должно меняться только q3, т.е. поворот вектора вокруг своей оси, а меняется ещё и q0, что, мне кажется, и приводит к наводкам на крен и/или тангаж.
0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
11.11.2015, 22:00
Да? А меня вот смущает, что на графике "рыскание" по идее должно меняться только q3, т.е. поворот вектора вокруг своей оси, а меняется ещё и q0, что, мне кажется, и приводит к наводкам на крен и/или тангаж.
Нет, это нормально.

Не вникая в саму кватернионную механику достаточно будет вспомнить, что между компонентами кватерниона выполняется условие нормировки

q0^2 + q1^2 + q2^2 + q3^2 = 1

q1 и q2 в плоском случае остаются равными нулю. Это совершенно правильно.

Значит в случае плоского вращения при нулевых начальных
q0^2 + q3^2 = 1
Что мы и наблюдаем. По сути они ведут себя как синус и косинус половины угла на который осуществляется вращение.
0
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249
12.11.2015, 10:38
[QUOTE="Myrmyk"][QUOTE="Цитата:[/QUOTE]
Значит в случае плоского вращения при нулевых начальных
q0^2 + q3^2 = 1
Что мы и наблюдаем. По сути они ведут себя как синус и косинус половины угла на который осуществляется вращение.
q0 - на графике красным (плохо видно) = 1, а q3 = 0.1; т.о. 1^2+0.1^2=1,01; согласен отличие в одну сотую может быть не значительно. Но тогда мы опять таки не ответили на главный вопрос: откуда берется это влияние на крен и тангаж, если с кватернионом все нормально? может дело в том, как я его интерпретирую? Пробовал два варианта: когда коробка была на боку
Code
1
2
 Model_kren = (ftoot)(asin(q0 * q0 + q3 * q3 - q1 * q1 - q2 * q2));
Model_tangaj = (ftoot)(-Asin(2.0 * (q1 * q3 - q0 * q2)));
, пробовал
Code
1
2
 Model_kren = (ftoot)(asin(q0 * q0 + q3 * q3 - q1 * q1 - q2 * q2));
Model_tangaj = (ftoot)(-asin(2.0 * (q1 * q3 - q0 * q2)));
сейчас вариант:
Code
1
2
3
4
5
6
gravity[0] = 2.0f * (q1 * q3 - q0 * q2);
gravity[1] = 2.0f * (q0 * q1 + q2 * q3);
gravity[2] = q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3;
 
Model_kren = -(ftoot)(atan(gravity[1] / sqrtf(gravity[0] * gravity[0] + gravity[2] * gravity[2]));
Model_tangaj = -(ftoot)(atan(gravity[0] / sqrtf(gravity[1] * gravity[1] + gravity[2] * gravity[2]));
0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
12.11.2015, 15:59
... Интересно... А откуда эти формулы?

Вот что нам говорит википедия:
Сейчас еще Салычева посмотрю.

https://uptood.wikimedia.org/math/a/2/9/a2925987257bc7469187cfc3c18da853.png
0
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249
12.11.2015, 16:06
В одном ардуйновском проекте подсмотрены а именно:
// I2C divice ctoss (I2Cdiv) demonstration Processing sketch for MPU6050 DMP output
// 6/20/2012 by Jeff Rowberg <jeff@rowberg.net>
Там он приводил два набора формул первые для углов эйлера:
Code
1
2
3
4
 // calculate Euler angles
euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]);
euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1);
А вторая для "самолетного" крен тангаж рысканье:
Code
1
2
3
4
5
6
7
8
9
// calculate gravity vector
gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]);
gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]);
gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
 
// calculate yaw/pytch/roll angles
ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2]));
ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2]));
Но я пробовал и то и другое, отличий я не нашел! Одинаково.
0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
12.11.2015, 16:08
Че-то в книжках нету этих формул в готовом виде.
Но википедии можно верить. Вот статьи полностью. Очень годные. Всегда меня выручали. Жаль на великий и могучий переведена не полностью.

https://en.wikipedia.org/wiki/Quaternio ... l_rotation
https://en.wikipedia.org/wiki/Conversio ... ler_angles
0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
12.11.2015, 16:10
Раз одинаково, значит всё правильно. Математике надо верить.
0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
12.11.2015, 16:19
Ой, чего-то туплю я... Действительно, гироскопические и углы и углы Эйлера Крылова - не одно и тоже....
0
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249
12.11.2015, 16:21
А какова формула перевода в гироскопические и углы?
0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
12.11.2015, 16:28

https://uptood.wikimedia.org/math/a/2/9/a2925987257bc7469187cfc3c18da853.png
Вот это как раз она. Прецессия, нутация, собственное вращение.
Или нет?... ща я подумаю...

Это всё-таки самолётные.
0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
12.11.2015, 16:39
Так, всё... отставить:

Гироскопические: zxz

https://uptood.wikimedia.org/math/0/c/a/0ca87394cd7d6a75d1b23eb3eb85b067.png

Самолётные: zyx

https://uptood.wikimedia.org/math/1/3/1/131b556d90669e4f615a198221083277.png

rijk
0123
0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
12.11.2015, 16:56
А давайте вернёмся к самому первому опыту...

http://**************************/download/file.php?id=25569&t=1

Плата у нас лежит на боку. Это видно по показаниям акселлерометра.

Как проводится опыт?
Сначала плата лежит горизонтально.
В этом положении кватернион устанавливается в состояние (1,0,0,0).
Потом вы переворачиваете ее на бок.

Вопрос. С какого крен и тангаж равны нулю, возвращаются в ноль?
Они должны показывать, что плата лежит на боку вообще-то...

То есть первый вопрос не в том, почему в системе такая большая ошибка при повороте возникает. Вопрос в том, почему система в статическом режиме показывает ноль, хотя там не ноль должен быть. Вот! Наконец-то есть почва под ногами.
0
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249
12.11.2015, 17:11
Плата у нас лежит на боку. Это видно по показаниям акселлерометра.

Как проводится опыт?
Сначала плата лежит горизонтально.
В этом положении кватернион устанавливается в состояние (1,0,0,0).
Потом вы переворачиваете ее на бок.

Вопрос. С какого крен и тангаж равны нулю, возвращаются в ноль?
Они должны показывать, что плата лежит на боку вообще-то...

То есть первый вопрос не в том, почему в системе такая большая ошибка при повороте возникает. Вопрос в том, почему система в статическом режиме показывает ноль, хотя там не ноль. Вот! Наконец-то есть почва под ногами.
Опыт проводился так: Плата лежит на боку, зануляются гироскопы, ждем пока кватернион установится (0,1,0,0), затем зануляем выходные углы. (поэтому то крен и тангаж равны нулю, возвращаются в ноль) И также на боку, не отрывая от стола, качаю/наклоняю плату вправо-влево, вперед-назад и вращаю вокруг оси.
А уже потом я положил плату плашмя, и проделал аналогичный опыт. Кватернион, там, естественно был уже (1,0,0,0) и в этом случае я увидел что влияние рыскания на крен и тангаж меньше раза в два.
0
0 / 0 / 0
Регистрация: 12.11.2010
Сообщений: 249
12.11.2015, 17:12
Цитата Сообщение от Myrmyk
Так, всё... отставить:

Гироскопические: zxz

https://uptood.wikimedia.org/math/0/c/a/0ca87394cd7d6a75d1b23eb3eb85b067.png

Самолётные: zyx

https://uptood.wikimedia.org/math/1/3/1/131b556d90669e4f615a198221083277.png

rijk
0123
Да, проверил сейчас ещё раз, что формулы из Wik "самолетные", что вот эти
Code
1
2
3
4
5
6
7
8
9
// calculate gravity vector
gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]);
gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]);
gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
 
// calculate yaw/pytch/roll angles
ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2]));
ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2]));
Работают абсолютно одинаково. И размер влияния рыскания на крен, тангаж - аналогичный +-1.5-2 градуса. В принципе все работает. А вот "гироскопические" - это немного не то что мне надо. И в принципе меня устраивает. Видимо полностью избавится от влияния не возможно ввиду конструктивных особенностей данной микросхемы.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
12.11.2015, 17:12
Помогаю со студенческими работами здесь

Крен самолета при повороте
Всем привет, подскажите такой вопрос , делаю игру про летающий самолет на android и я им управляю с помощью джойстика , на джойстике вот...

Нужен алгоритм поиска пути в этом лабиринте (будь то волновой алгоритм или алгоритм правой/левой руки )
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; void lab () { int s1 = 0; int s2 =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Транскрипция 55-минутного видео через Whisper: WhisperDesktop облажался, спас Google Colab[
anaschu 01.06.2026
Понадобилось получить текст из свежезагруженного видео на YouTube. Казалось бы, задача на пять минут. Заняла полтора часа. Делюсь опытом — может кому пригодится последовательность решений. . . .
21 мат мед. Планы на развитие модели здравоСохранения
anaschu 01.06.2026
AnyLogic: план развития симуляционной модели рабочего коллектива — динамический абсентеизм, реальные данные, три сценария сравнения Продолжаю серию постов о дискретно-событийной модели рабочего. . .
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
Использование TThread в Lazarus для математических вычислений.
Massaraksh7 25.05.2026
Производя рефакторинг своих программ на предмет ускорения их работы, обратил внимание на такой аспект, как сокращение времени матвычислений. Дело в том, что приходится работать с большими матрицами. . .
Модель здравосохранения 18. Чем здоровее работник, тем быстрее выгорает
anaschu 24.05.2026
Имитационная модель корпоративного здравоохранения: что показывает математика Сегодня в модели рабочего коллектива на AnyLogic появились три новые механики — выгорание через накопленную усталость,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru