1
1
#include " float3vector.h"
2
2
#include " float3matrix.h"
3
3
#include " quaternion.h"
4
+ #include " AHRS.h"
4
5
5
6
const float ldi[]={0 .1f , +0 .25f , -10 .0f }; // left wing down
6
7
const float rdi[]={0 .1f , -0 .15f , -10 .0f }; // right wing down
@@ -18,73 +19,122 @@ void setup_tester(void)
18
19
float3vector horiz_body ( hi);
19
20
20
21
// setup the sensor orientation to test
21
- quaternion<float >sensor_q;
22
+ quaternion<float >q_sensor_2_body;
23
+ // q_sensor_2_body.from_euler( 0 * M_PI/180.0, 0 * M_PI/180.0, 13 * M_PI/180.0);
24
+ q_sensor_2_body.from_euler ( 90 * M_PI/180.0 , 180.0 * M_PI/180.0 , -30 * M_PI/180.0 );
22
25
// sensor_q.from_euler( 45.0 * M_PI/180.0, 135.0 * M_PI/180.0, -30.0 * M_PI/180.0);
23
26
// sensor_q.from_euler( -135.0 * M_PI/180.0, 45.0 * M_PI/180.0, 150.0 * M_PI/180.0);
24
27
// sensor_q.from_euler( -10.0 * M_PI/180.0, 75.0 * M_PI/180.0, -45.0 * M_PI/180.0);
25
- sensor_q.from_euler ( 10.0 * M_PI/180.0 , -75.0 * M_PI/180.0 , +125.0 * M_PI/180.0 );
28
+ // sensor_q.from_euler( 10.0 * M_PI/180.0, -75.0 * M_PI/180.0, +125.0 * M_PI/180.0);
26
29
27
- float3matrix sensor_2_body_assumption ;
28
- sensor_q .get_rotation_matrix (sensor_2_body_assumption );
30
+ float3matrix m_sensor_2_body_assumption ;
31
+ q_sensor_2_body .get_rotation_matrix ( m_sensor_2_body_assumption );
29
32
30
33
// check if we get the rotation angles using the matrix given
31
- quaternion<float > qin ;
32
- qin .from_rotation_matrix (sensor_2_body_assumption );
33
- eulerangle<float > euler_in = qin ;
34
+ quaternion<float > q_sensor_2_body_assumption ;
35
+ q_sensor_2_body_assumption .from_rotation_matrix (m_sensor_2_body_assumption );
36
+ eulerangle<float > euler_in = q_sensor_2_body_assumption ;
34
37
euler_in.roll *= 180 /M_PI;
35
38
euler_in.pitch *= 180 /M_PI;
36
39
euler_in.yaw *= 180 /M_PI;
37
40
38
41
// map measurements into the sensor frame
39
- float3vector left_down_sensor = sensor_2_body_assumption .reverse_map ( left_down_body);
40
- float3vector right_down_sensor= sensor_2_body_assumption .reverse_map ( right_down_body);
41
- float3vector horiz_sensor = sensor_2_body_assumption .reverse_map ( horiz_body);
42
+ float3vector v_left_down_sensor = m_sensor_2_body_assumption .reverse_map ( left_down_body);
43
+ float3vector v_right_down_sensor= m_sensor_2_body_assumption .reverse_map ( right_down_body);
44
+ float3vector v_horiz_sensor = m_sensor_2_body_assumption .reverse_map ( horiz_body);
42
45
43
46
// resolve sensor orientation using measurements
44
- float3vector front_down_sensor_helper = right_down_sensor .vector_multiply (left_down_sensor );
45
- float3vector u_right_sensor = front_down_sensor_helper.vector_multiply (horiz_sensor );
47
+ float3vector front_down_sensor_helper = v_right_down_sensor .vector_multiply (v_left_down_sensor );
48
+ float3vector u_right_sensor = front_down_sensor_helper.vector_multiply (v_horiz_sensor );
46
49
u_right_sensor.normalize ();
47
50
48
- float3vector u_down_sensor = horiz_sensor * -1 .0f ;
51
+ float3vector u_down_sensor = v_horiz_sensor * -1 .0f ;
49
52
u_down_sensor.normalize ();
50
53
51
54
float3vector u_front_sensor=u_right_sensor.vector_multiply (u_down_sensor);
52
55
u_front_sensor.normalize ();
53
56
54
57
// calculate the rotation matrix using our calibration data
55
- float3matrix sensor_2_body ;
56
- sensor_2_body .e [0 ][0 ]=u_front_sensor[0 ];
57
- sensor_2_body .e [0 ][1 ]=u_front_sensor[1 ];
58
- sensor_2_body .e [0 ][2 ]=u_front_sensor[2 ];
58
+ float3matrix m_sensor_2_body ;
59
+ m_sensor_2_body .e [FRONT ][0 ]=u_front_sensor[0 ];
60
+ m_sensor_2_body .e [FRONT ][1 ]=u_front_sensor[1 ];
61
+ m_sensor_2_body .e [FRONT ][2 ]=u_front_sensor[2 ];
59
62
60
- sensor_2_body .e [1 ][0 ]=u_right_sensor[0 ];
61
- sensor_2_body .e [1 ][1 ]=u_right_sensor[1 ];
62
- sensor_2_body .e [1 ][2 ]=u_right_sensor[2 ];
63
+ m_sensor_2_body .e [RIGHT ][0 ]=u_right_sensor[0 ];
64
+ m_sensor_2_body .e [RIGHT ][1 ]=u_right_sensor[1 ];
65
+ m_sensor_2_body .e [RIGHT ][2 ]=u_right_sensor[2 ];
63
66
64
- sensor_2_body .e [2 ][0 ]=u_down_sensor[0 ];
65
- sensor_2_body .e [2 ][1 ]=u_down_sensor[1 ];
66
- sensor_2_body .e [2 ][2 ]=u_down_sensor[2 ];
67
+ m_sensor_2_body .e [DOWN ][0 ]=u_down_sensor[0 ];
68
+ m_sensor_2_body .e [DOWN ][1 ]=u_down_sensor[1 ];
69
+ m_sensor_2_body .e [DOWN ][2 ]=u_down_sensor[2 ];
67
70
68
71
// test if the rotation matrix recovers the body frame data
69
- float3vector test_left_down_body = sensor_2_body * left_down_sensor ;
70
- float3vector test_right_down_body = sensor_2_body * right_down_sensor ;
71
- float3vector test_horiz_body = sensor_2_body * horiz_sensor ;
72
+ float3vector test_left_down_body = m_sensor_2_body * v_left_down_sensor ;
73
+ float3vector test_right_down_body = m_sensor_2_body * v_right_down_sensor ;
74
+ float3vector test_horiz_body = m_sensor_2_body * v_horiz_sensor ;
72
75
73
76
// test if the matrix provides pure rotation
74
- float3vector vtest1 = sensor_2_body * float3vector ( test1);
77
+ float3vector vtest1 = m_sensor_2_body * float3vector ( test1);
75
78
float test1_abs=vtest1.abs ();
76
- float3vector vtest2 = sensor_2_body * float3vector ( test2);
79
+ float3vector vtest2 = m_sensor_2_body * float3vector ( test2);
77
80
float test2_abs=vtest2.abs ();
78
- float3vector vtest3 = sensor_2_body * float3vector ( test3);
81
+ float3vector vtest3 = m_sensor_2_body * float3vector ( test3);
79
82
float test3_abs=vtest3.abs ();
80
83
81
84
// check if we get the rotation angles using the matrix we have calculated
82
85
quaternion<float > q;
83
- q.from_rotation_matrix (sensor_2_body );
86
+ q.from_rotation_matrix (m_sensor_2_body );
84
87
eulerangle<float > euler = q;
85
88
euler.roll *= 180 /M_PI;
86
89
euler.pitch *= 180 /M_PI;
87
90
euler.yaw *= 180 /M_PI;
91
+
92
+ // //////////////////////////////////////////////////////////////////////////////////////////////
93
+
94
+ // pitch and roll axis fine tuning
95
+ float pitch_angle = 0 .5f ; // sensor nose is higher than configured
96
+ float roll_angle = -0 .3f ; // sensor is looking more left than configured
97
+ quaternion<float >q_sensor_ideal_2_misaligned;
98
+ q_sensor_ideal_2_misaligned.from_euler ( roll_angle, pitch_angle, ZERO);
99
+
100
+ quaternion<float >q_body_2_world; // looking NE horizontally
101
+ q_body_2_world.from_euler ( ZERO, ZERO, 45 .0f * M_PI_F / 180 .0f );
102
+ // q_body_2_world.from_euler( ZERO, ZERO, -145.0f * M_PI_F / 180.0f);
103
+
104
+ // provide simulated measurement
105
+ quaternion <float > q_misaligned_sensor_2_world = q_sensor_ideal_2_misaligned;
106
+ q_misaligned_sensor_2_world *= q_sensor_2_body;
107
+ q_misaligned_sensor_2_world *= q_body_2_world;
108
+
109
+ euler = q_misaligned_sensor_2_world;
110
+ euler.roll *= 180 /M_PI;
111
+ euler.pitch *= 180 /M_PI;
112
+ euler.yaw *= 180 /M_PI;
113
+
114
+ float3matrix m_misaligned_sensor_to_world;
115
+ q_misaligned_sensor_2_world.get_rotation_matrix ( m_misaligned_sensor_to_world);
116
+
117
+ // simulate measurement
118
+ float3vector v_down;
119
+ v_down[DOWN] = -10 .0f ;
120
+ float3vector v_measurement_sensor = m_misaligned_sensor_to_world.reverse_map ( v_down);
121
+
122
+ q_sensor_2_body.get_rotation_matrix ( m_sensor_2_body);
123
+
124
+ float3vector v_measurement_body = m_sensor_2_body * v_measurement_sensor;
125
+
126
+ float3matrix m_body_2_world;
127
+ q_body_2_world.get_rotation_matrix (m_body_2_world);
128
+ float3vector v_measurement_world = m_body_2_world * v_measurement_body;
129
+
130
+ float pitch_angle_measured = ATAN2 ( -v_measurement_world[0 ], -v_measurement_world[2 ]);
131
+ float roll_angle_measured = ATAN2 ( -v_measurement_world[1 ], -v_measurement_world[2 ]);
132
+
133
+ // compute corrected sensor alignment quaternion
134
+ quaternion <float > q_correction;
135
+ q_correction.from_euler ( roll_angle_measured, pitch_angle_measured, ZERO);
136
+
137
+ quaternion<float > q_corrected_sensor_orientation;
88
138
}
89
139
90
140
0 commit comments