Sensor Fusion Library 0.6.1
Orientation sensing for Espressif (ESP32, ESP8266) processors
Loading...
Searching...
No Matches
fusion_testing.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
26#include <stdlib.h>
27#include "sensor_fusion.h"
28#include "control.h"
29#include "build.h"
30
37{
38#ifdef INCLUDE_DEBUG_FUNCTIONS
39 // volatile keyword used to force compiler not to optimize out these
40 // variables. this does unfortunately result in a couple of warnings (which
41 // can be ignored) farther down in this code.
42 volatile static uint16_t iTestProgress;
43 volatile static uint16_t iTestDelay = 0;
44 //volatile static uint16_t iTestAngle = 0; ///< Integer Residual angle associated with measured delay
45 volatile float angle=0.0f;
46 volatile static float threshold=0;
47 static Quaternion StartingQ = {
48 .q0 = 1.0,
49 .q1 = 0.0,
50 .q2 = 0.0,
51 .q3 = 0.0
52 };
53 Quaternion CurrentQ = {
54 .q0 = 1.0,
55 .q1 = 0.0,
56 .q2 = 0.0,
57 .q3 = 0.0
58 };
59 // cache local copies of control flags so we don't have to keep dereferencing pointers below
60 quaternion_type quaternionPacketType;
61 quaternionPacketType = sfg->pControlSubsystem->QuaternionPacketType;
62
63 Quaternion ftmpq; // scratch quaternion
64
65 // calculate the test perturbation
66 switch (sfg->iPerturbation)
67 {
68 case 1: // 180 degrees about X
69 ftmpq.q0 = 0.0F;
70 ftmpq.q1 = 1.0F;
71 ftmpq.q2 = 0.0F;
72 ftmpq.q3 = 0.0F;
73 threshold = 90.0;
74 break;
75
76 case 2: // 180 degrees about Y
77 ftmpq.q0 = 0.0F;
78 ftmpq.q1 = 0.0F;
79 ftmpq.q2 = 1.0F;
80 ftmpq.q3 = 0.0F;
81 threshold = 90.0;
82 break;
83
84 case 3: // 180 degrees about Z
85 ftmpq.q0 = 0.0F;
86 ftmpq.q1 = 0.0F;
87 ftmpq.q2 = 0.0F;
88 ftmpq.q3 = 1.0F;
89 threshold = 90.0;
90 break;
91
92 case 4: // -90 degrees about X
93 ftmpq.q0 = ONEOVERSQRT2;
94 ftmpq.q1 = -ONEOVERSQRT2;
95 ftmpq.q2 = 0.0F;
96 ftmpq.q3 = 0.0F;
97 threshold = 45.0;
98 break;
99
100 case 5: // +90 degrees about X
101 ftmpq.q0 = ONEOVERSQRT2;
102 ftmpq.q1 = ONEOVERSQRT2;
103 ftmpq.q2 = 0.0F;
104 ftmpq.q3 = 0.0F;
105 threshold = 45.0;
106 break;
107
108 case 6: // -90 degrees about Y
109 ftmpq.q0 = ONEOVERSQRT2;
110 ftmpq.q1 = 0.0F;
111 ftmpq.q2 = -ONEOVERSQRT2;
112 ftmpq.q3 = 0.0F;
113 threshold = 45.0;
114 break;
115
116 case 7: // +90 degrees about Y
117 ftmpq.q0 = ONEOVERSQRT2;
118 ftmpq.q1 = 0.0F;
119 ftmpq.q2 = ONEOVERSQRT2;
120 ftmpq.q3 = 0.0F;
121 threshold = 45.0;
122 break;
123
124 case 8: // -90 degrees about Z
125 ftmpq.q0 = ONEOVERSQRT2;
126 ftmpq.q1 = 0.0F;
127 ftmpq.q2 = 0.0F;
128 ftmpq.q3 = -ONEOVERSQRT2;
129 threshold = 45.0;
130 break;
131
132 case 9: // +90 degrees about Z
133 ftmpq.q0 = ONEOVERSQRT2;
134 ftmpq.q1 = 0.0F;
135 ftmpq.q2 = 0.0F;
136 ftmpq.q3 = ONEOVERSQRT2;
137 threshold = 45.0;
138 break;
139
140 default: // No rotation
141 ftmpq.q0 = 1.0F;
142 ftmpq.q1 = 0.0F;
143 ftmpq.q2 = 0.0F;
144 ftmpq.q3 = 0.0F;
145 break;
146 }
147
148 switch (quaternionPacketType) {
149#if F_3DOF_G_BASIC
150 case (Q3):
151 CurrentQ = sfg->SV_3DOF_G_BASIC.fLPq;
152 qAeqAxB(&(sfg->SV_3DOF_G_BASIC.fLPq), &ftmpq);
153 break;
154#endif
155#if F_3DOF_B_BASIC
156 case (Q3M):
157 CurrentQ = sfg->SV_3DOF_B_BASIC.fLPq;
158 qAeqAxB(&(sfg->SV_3DOF_B_BASIC.fLPq), &ftmpq);
159 break;
160#endif
161#if F_3DOF_Y_BASIC
162 case (Q3G):
163 CurrentQ = sfg->SV_3DOF_Y_BASIC.fq;
164 qAeqAxB(&(sfg->SV_3DOF_Y_BASIC.fq), &ftmpq);
165 break;
166#endif
167#if F_6DOF_GB_BASIC
168 case (Q6MA):
169 CurrentQ = sfg->SV_6DOF_GB_BASIC.fLPq;
170 qAeqAxB(&(sfg->SV_6DOF_GB_BASIC.fLPq), &ftmpq);
171 break;
172#endif
173#if F_6DOF_GY_KALMAN
174 case (Q6AG):
175 CurrentQ = sfg->SV_6DOF_GY_KALMAN.fqPl;
176 qAeqAxB(&(sfg->SV_6DOF_GY_KALMAN.fqPl), &ftmpq);
177 break;
178#endif
179#if F_9DOF_GBY_KALMAN
180 case (Q9):
181 CurrentQ = sfg->SV_9DOF_GBY_KALMAN.fqPl;
182 qAeqAxB(&(sfg->SV_9DOF_GBY_KALMAN.fqPl), &ftmpq);
183 break;
184#endif
185 default:
186 CurrentQ.q0 = 1.0;
187 CurrentQ.q1 = 0.0;
188 CurrentQ.q2 = 0.0;
189 CurrentQ.q3 = 0.0;
190 break;
191 }
192
193 // Begin of code for white-box testing - requires IAR debugger
194 switch (iTestProgress) {
195 case 0: // no test in progress, check to see if we should start one
196 if (sfg->iPerturbation>0) {
197 // Start Test
198 iTestProgress = 1;
199 sfg->iPerturbation = 0;
200 iTestDelay = 0;
201 //iTestAngle = 0;
202 // We'll need the complex conjugate of the starting quaternion
203 StartingQ.q0 = CurrentQ.q0;
204 StartingQ.q1 = -1 * CurrentQ.q1;
205 StartingQ.q2 = -1 * CurrentQ.q2;
206 StartingQ.q3 = -1 * CurrentQ.q3;
207 }
208 break;
209 default: // Test in progress, check to see if trigger reached
210 iTestDelay += 1;
211 qAeqAxB(&CurrentQ, &StartingQ);
212 angle = 2 * F180OVERPI * acos(CurrentQ.q0);
213 angle = fmod(fabs(angle), 180.0);
214 //iTestAngle = (uint16_t) (10 * angle);
215 // In IAR, you can use a Log breakpoint to monitor "return to stationary pose".
216 // Use the following expression in the Message field and check the
217 // checkbox for C-Spy macro. Then Click any of the "Test" buttons
218 // in the Sensor Fusion Toolbox and monitor the results in the Messages window.
219 //"Delay=", iTestDelay:%d, " Angle=",iTestAngle:%d
220 if (angle<threshold) iTestProgress=2; // triggered
221 if (angle < (0.2 * threshold)) iTestProgress=0; // test is done
222 if (iTestDelay>100) iTestProgress=0; // abort test
223 break;
224 }
225 // End of code for white-box testing
226#endif
227}
Build configuration file.
Defines control sub-system.
void qAeqAxB(Quaternion *pqA, const Quaternion *pqB)
function compute the quaternion product qA = qA * qB
The sensor_fusion.h file implements the top level programming interface.
#define ONEOVERSQRT2
1/sqrt(2)
enum quaternion quaternion_type
the quaternion type to be transmitted
@ Q6MA
Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
@ Q3
Quaternion derived from 3-axis accel (tilt)
@ Q6AG
Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
@ Q9
Quaternion derived from full 9-axis sensor fusion.
@ Q3M
Quaternion derived from 3-axis mag only (auto compass algorithm)
@ Q3G
Quaternion derived from 3-axis gyro only (rotation)
#define F180OVERPI
radians to degrees conversion = 180 / pi
applyPerturbation_t ApplyPerturbation
ApplyPerturbation is a reverse unit-step test function.
quaternion structure definition
Definition orientation.h:25
float q3
z vector component
Definition orientation.h:29
float q0
scalar component
Definition orientation.h:26
float q1
x vector component
Definition orientation.h:27
float q2
y vector component
Definition orientation.h:28
The top level fusion structure.
volatile uint8_t iPerturbation
test perturbation to be applied