11#include " float3vector.h"
22#include " float3matrix.h"
33#include " quaternion.h"
4+ #include " AHRS.h"
45
56const float ldi[]={0 .1f , +0 .25f , -10 .0f }; // left wing down
67const float rdi[]={0 .1f , -0 .15f , -10 .0f }; // right wing down
@@ -18,73 +19,122 @@ void setup_tester(void)
1819 float3vector horiz_body ( hi);
1920
2021 // 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 );
2225// sensor_q.from_euler( 45.0 * M_PI/180.0, 135.0 * M_PI/180.0, -30.0 * M_PI/180.0);
2326// sensor_q.from_euler( -135.0 * M_PI/180.0, 45.0 * M_PI/180.0, 150.0 * M_PI/180.0);
2427// 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);
2629
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 );
2932
3033 // 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 ;
3437 euler_in.roll *= 180 /M_PI;
3538 euler_in.pitch *= 180 /M_PI;
3639 euler_in.yaw *= 180 /M_PI;
3740
3841 // 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);
4245
4346 // 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 );
4649 u_right_sensor.normalize ();
4750
48- float3vector u_down_sensor = horiz_sensor * -1 .0f ;
51+ float3vector u_down_sensor = v_horiz_sensor * -1 .0f ;
4952 u_down_sensor.normalize ();
5053
5154 float3vector u_front_sensor=u_right_sensor.vector_multiply (u_down_sensor);
5255 u_front_sensor.normalize ();
5356
5457 // 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 ];
5962
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 ];
6366
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 ];
6770
6871 // 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 ;
7275
7376 // test if the matrix provides pure rotation
74- float3vector vtest1 = sensor_2_body * float3vector ( test1);
77+ float3vector vtest1 = m_sensor_2_body * float3vector ( test1);
7578 float test1_abs=vtest1.abs ();
76- float3vector vtest2 = sensor_2_body * float3vector ( test2);
79+ float3vector vtest2 = m_sensor_2_body * float3vector ( test2);
7780 float test2_abs=vtest2.abs ();
78- float3vector vtest3 = sensor_2_body * float3vector ( test3);
81+ float3vector vtest3 = m_sensor_2_body * float3vector ( test3);
7982 float test3_abs=vtest3.abs ();
8083
8184 // check if we get the rotation angles using the matrix we have calculated
8285 quaternion<float > q;
83- q.from_rotation_matrix (sensor_2_body );
86+ q.from_rotation_matrix (m_sensor_2_body );
8487 eulerangle<float > euler = q;
8588 euler.roll *= 180 /M_PI;
8689 euler.pitch *= 180 /M_PI;
8790 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;
88138}
89139
90140
0 commit comments