annotate src/compass.c @ 650:bc214815deb2

3.19/10.75 release
author heinrichsweikamp
date Sun, 28 Aug 2022 13:13:38 +0200
parents cd58f7fc86db
children 75e90cd0c2c3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
282
7d9edd3b8c86 Make a more compact COMPASS calibration code (<7KB), and add more tests.
jDG
parents: 214
diff changeset
1 //////////////////////////////////////////////////////////////////////////////
7d9edd3b8c86 Make a more compact COMPASS calibration code (<7KB), and add more tests.
jDG
parents: 214
diff changeset
2 /// compass.c
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
3 /// Compute north direction from magnetic/acceleration measures V3.02.1
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
4 ///
282
7d9edd3b8c86 Make a more compact COMPASS calibration code (<7KB), and add more tests.
jDG
parents: 214
diff changeset
5 /// Copyright (c) 2012-2015, JD Gascuel, HeinrichsWeikamp, all right reserved.
0
heinrichsweikamp
parents:
diff changeset
6 //////////////////////////////////////////////////////////////////////////////
heinrichsweikamp
parents:
diff changeset
7 // HISTORY
heinrichsweikamp
parents:
diff changeset
8 // 2012-12-01 [jDG] Creation
heinrichsweikamp
parents:
diff changeset
9 // 2012-12-23 [jDG] Added filtering.
heinrichsweikamp
parents:
diff changeset
10 // 2012-12-30 [jDG] Added calibration (spherical best fit).
282
7d9edd3b8c86 Make a more compact COMPASS calibration code (<7KB), and add more tests.
jDG
parents: 214
diff changeset
11 // 2015-05-22 [jDG] Minor cleanups. Smaller calibration code.
0
heinrichsweikamp
parents:
diff changeset
12
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
13 #include "configuration.inc"
0
heinrichsweikamp
parents:
diff changeset
14 #include "compass.h"
heinrichsweikamp
parents:
diff changeset
15
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
16
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
17 #ifdef _compass
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
18
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
19
0
heinrichsweikamp
parents:
diff changeset
20 //////////////////////////////////////////////////////////////////////////////
650
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
21 //
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
22 // Put compass data into bank 13 (stack) and bank 9 (variables)
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
23 //
0
heinrichsweikamp
parents:
diff changeset
24 #ifndef UNIX
650
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
25 # pragma udata overlay bank13=0xd00
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
26 static char C_STACK[256]; // overlay C-code data stack here
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
27 # define C_STACK_ADDR C_STACK
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
28 # define RESET_C_STACK \
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
29 _asm \
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
30 LFSR 1,C_STACK_ADDR \
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
31 LFSR 2,C_STACK_ADDR \
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
32 _endasm
650
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
33 # pragma udata bank9a = 0x900
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
34 # pragma code compass_run
650
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
35 # define PARAMETER static
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
36 # define OVERLAY overlay
0
heinrichsweikamp
parents:
diff changeset
37 #else
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
38 # define RESET_C_STACK
650
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
39 # define PARAMETER
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
40 # define OVERLAY
0
heinrichsweikamp
parents:
diff changeset
41 #endif
heinrichsweikamp
parents:
diff changeset
42
650
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
43
0
heinrichsweikamp
parents:
diff changeset
44 //////////////////////////////////////////////////////////////////////////////
heinrichsweikamp
parents:
diff changeset
45 // fifth order of polynomial approximation of atan(), giving 0.05 deg max error
heinrichsweikamp
parents:
diff changeset
46 //
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
47 #define K1 (5701) // needs K1/2**16
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
48 #define K2 (1645) // needs K2/2**48 WAS NEGATIV
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
49 #define K3 ( 446) // needs K3/2**80
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
50
0
heinrichsweikamp
parents:
diff changeset
51
heinrichsweikamp
parents:
diff changeset
52 //////////////////////////////////////////////////////////////////////////////
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
53 // Interface to assembler multiplies
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
54
0
heinrichsweikamp
parents:
diff changeset
55 Int16 umul(PARAMETER Int16 a, PARAMETER Int16 b)
heinrichsweikamp
parents:
diff changeset
56 {
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
57 extern Int16 compass_umul(void);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
58 extern Int16 compass_a, compass_b;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
59 compass_a = a;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
60 compass_b = b;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
61 return compass_umul();
0
heinrichsweikamp
parents:
diff changeset
62 }
heinrichsweikamp
parents:
diff changeset
63
heinrichsweikamp
parents:
diff changeset
64 Int16 imul(PARAMETER Int16 a, PARAMETER Int16 b)
heinrichsweikamp
parents:
diff changeset
65 {
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
66 extern Int16 compass_imul(void);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
67 extern Int16 compass_a, compass_b;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
68 compass_a = a;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
69 compass_b = b;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
70 return compass_imul();
0
heinrichsweikamp
parents:
diff changeset
71 }
heinrichsweikamp
parents:
diff changeset
72
heinrichsweikamp
parents:
diff changeset
73 //////////////////////////////////////////////////////////////////////////////
heinrichsweikamp
parents:
diff changeset
74 /// Returns a / b * 2**16
heinrichsweikamp
parents:
diff changeset
75 ///
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
76 /// A 16/16 -> 16 bits divide, returning a scaled result.
0
heinrichsweikamp
parents:
diff changeset
77 /// Used to multiply fractional numbers in the range 0..1,
heinrichsweikamp
parents:
diff changeset
78 /// represented as 0..32767.
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
79
0
heinrichsweikamp
parents:
diff changeset
80 Int16 udiv(PARAMETER Int16 a, PARAMETER Int16 b)
heinrichsweikamp
parents:
diff changeset
81 {
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
82 OVERLAY Int16 d, r;
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
83 OVERLAY char failsafe=250;
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
84
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
85 //---- Pre-scale both numerator and denominator --------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
86 while( (((a>>8) | (b>>8)) & 0xC0) == 0 )
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
87 {
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
88 failsafe--;
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
89 if( failsafe == 0 ) break;
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
90
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
91 a <<= 1;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
92 b <<= 1;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
93 }
0
heinrichsweikamp
parents:
diff changeset
94
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
95 //---- Make division trials ----------------------------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
96 d = 0x4000; // start with 0.5, because 1.0 is sign bit
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
97 b >>= 1; // hence pre-shift b
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
98 r = 0;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
99 do {
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
100 if( a >= b ) // a is big enough ?
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
101 {
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
102 a -= b; // then count d times b out of it
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
103 r |= d; // and accumulate that bit
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
104 }
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
105 b >>= 1; // then loop trying twice smaller
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
106 d >>= 1;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
107 } while( b );
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
108 return r;
0
heinrichsweikamp
parents:
diff changeset
109 }
heinrichsweikamp
parents:
diff changeset
110
heinrichsweikamp
parents:
diff changeset
111 //////////////////////////////////////////////////////////////////////////////
heinrichsweikamp
parents:
diff changeset
112 /// Computes atan(y/x) in Angle, for x, y in range 0..32767
heinrichsweikamp
parents:
diff changeset
113 ///
heinrichsweikamp
parents:
diff changeset
114 /// Results a single quadrant Angle, in the range 0 .. Q_PI/2
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
115
0
heinrichsweikamp
parents:
diff changeset
116 Angle utan(PARAMETER Int16 y, PARAMETER Int16 x)
heinrichsweikamp
parents:
diff changeset
117 {
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
118 OVERLAY Int16 ratio, angle, x2, x3;
0
heinrichsweikamp
parents:
diff changeset
119
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
120 //---- Handle zero divisor -----------------------------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
121 if( x == 0 )
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
122 return (y == 0) ? 0 : Q_PIO2;
0
heinrichsweikamp
parents:
diff changeset
123
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
124 //---- Make it half-quadrant : 0 .. 45 deg -------------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
125 ratio = (x > y) ? udiv(y, x) : udiv(x, y);
0
heinrichsweikamp
parents:
diff changeset
126
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
127 //---- Then apply the polynomial approximation ---------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
128 angle = umul(K1, ratio); // r*K1 / 2**16
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
129 x2 = umul(ratio, ratio); // r**2 / 2**16
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
130 x3 = umul(x2, ratio); // r**3 / 2**32
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
131 angle -= umul(x3, K2); // K2*r**3 / 2**48: NEGATIV.
0
heinrichsweikamp
parents:
diff changeset
132
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
133 x3 = umul(x3, x2); // r**5 / 2**64
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
134 angle += umul(x3, K3); // K3*r**5 / 2**80
0
heinrichsweikamp
parents:
diff changeset
135
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
136 //---- Recover the full quadrant -----------------------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
137 return (x < y) ? (Angle)(Q_PIO2 - angle)
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
138 : (Angle)(angle);
0
heinrichsweikamp
parents:
diff changeset
139 }
heinrichsweikamp
parents:
diff changeset
140
heinrichsweikamp
parents:
diff changeset
141 //////////////////////////////////////////////////////////////////////////////
heinrichsweikamp
parents:
diff changeset
142 /// Computes atan2(y/x) in Angle, for x, y in range -32768 to 32767
heinrichsweikamp
parents:
diff changeset
143 ///
heinrichsweikamp
parents:
diff changeset
144 /// Results a four quadrant Angle, in the range -Q_PI .. +Q_PI
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
145
0
heinrichsweikamp
parents:
diff changeset
146 Angle itan(PARAMETER Int16 y, PARAMETER Int16 x)
heinrichsweikamp
parents:
diff changeset
147 {
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
148 // Beware: -32768 is not properly handled (sign error)
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
149 if( x == -32768 ) x = -32767;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
150 if( y == -32768 ) y = -32767;
0
heinrichsweikamp
parents:
diff changeset
151
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
152 if( x >= 0 )
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
153 if( y >= 0 ) // first quadrant: 0..90 deg.
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
154 return utan(y,x);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
155 else // fourth quadrant: 0..-90 deg
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
156 return -utan(-y,x);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
157 else
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
158 if( y >= 0 ) // second quadrant: 90..180 deg
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
159 return Q_PI - utan(y, -x);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
160 else // third quadrant: -90..-180 deg;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
161 return -Q_PI + utan(-y, -x);
0
heinrichsweikamp
parents:
diff changeset
162 }
heinrichsweikamp
parents:
diff changeset
163
heinrichsweikamp
parents:
diff changeset
164 //////////////////////////////////////////////////////////////////////////////
heinrichsweikamp
parents:
diff changeset
165 /// Computes cos(theta) = sqrtf(x2/h2),
heinrichsweikamp
parents:
diff changeset
166 /// when theta = atan(y/x) and h2=x*x+y*y
heinrichsweikamp
parents:
diff changeset
167 ///
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
168
0
heinrichsweikamp
parents:
diff changeset
169 Int16 cosxh(PARAMETER Int16 x2, PARAMETER Int16 h2)
heinrichsweikamp
parents:
diff changeset
170 {
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
171 OVERLAY Int16 r = 0;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
172 OVERLAY Int16 d = 0x4000;
0
heinrichsweikamp
parents:
diff changeset
173
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
174 do {
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
175 OVERLAY Int16 a = r + d;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
176 a = umul(a, a);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
177 a = umul(a, h2);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
178 if( a <= x2 ) r += d;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
179 d >>= 1;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
180 } while( d );
0
heinrichsweikamp
parents:
diff changeset
181
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
182 return r;
0
heinrichsweikamp
parents:
diff changeset
183 }
heinrichsweikamp
parents:
diff changeset
184
heinrichsweikamp
parents:
diff changeset
185 //////////////////////////////////////////////////////////////////////////////
heinrichsweikamp
parents:
diff changeset
186 /// Computes both sin and cos of angle y/x,
heinrichsweikamp
parents:
diff changeset
187 /// with h = sqrt(x**2+y**2).
heinrichsweikamp
parents:
diff changeset
188 ///
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
189
0
heinrichsweikamp
parents:
diff changeset
190 void sincos(PARAMETER Int16 x, PARAMETER Int16 y, Int16* sin, Int16* cos)
heinrichsweikamp
parents:
diff changeset
191 {
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
192 OVERLAY Int16 x2, y2, h2;
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
193 OVERLAY char failsafe = 250;
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
194
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
195 //---- Fold into one quadrant --------------------------------------------
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
196 OVERLAY char neg = 0;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
197 if( x < 0 )
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
198 {
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
199 neg |= 1;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
200 x = -x;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
201 }
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
202 if( y < 0 )
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
203 {
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
204 neg |= 2;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
205 y = -y;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
206 }
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
207
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
208 //---- Pre-scale both numerator and denominator ----------------------
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
209 while( (((x>>8) | (y>>8)) & 0xE0) == 0 )
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
210 {
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
211 failsafe--;
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
212 if( failsafe == 0 ) break;
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
213
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
214 x <<= 1;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
215 y <<= 1;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
216 }
0
heinrichsweikamp
parents:
diff changeset
217
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
218 //---- Uses trig() to do the stuff one on quadrant -------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
219 x2 = umul(x,x);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
220 y2 = umul(y,y);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
221 h2 = x2 + y2;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
222 x2 = cosxh(x2, h2);
0
heinrichsweikamp
parents:
diff changeset
223
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
224 //---- Results back in four quadrants --------------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
225 *cos = (neg & 1) ? -x2 : x2;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
226 y2 = cosxh(y2, h2);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
227 *sin = (neg & 2) ? -y2 : y2;
0
heinrichsweikamp
parents:
diff changeset
228 }
heinrichsweikamp
parents:
diff changeset
229
heinrichsweikamp
parents:
diff changeset
230 //////////////////////////////////////////////////////////////////////////////
heinrichsweikamp
parents:
diff changeset
231 //
heinrichsweikamp
parents:
diff changeset
232
heinrichsweikamp
parents:
diff changeset
233 void compass(void)
heinrichsweikamp
parents:
diff changeset
234 {
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
235 OVERLAY Int16 sin, cos;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
236 OVERLAY Int16 iBfx, iBfy, Gz;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
237 OVERLAY Int16 iBpx, iBpy, iBpz;
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
238
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
239 RESET_C_STACK;
0
heinrichsweikamp
parents:
diff changeset
240
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
241 //---- Detect uncalibrated compass ---------------------------------------
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
242 if( !compass_CX_f && !compass_CY_f && !compass_CZ_f )
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
243 {
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
244 // no usable compass is signaled by bit 15 set to 1
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
245 compass_heading_new = 32768;
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
246 return;
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
247 }
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
248
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
249 //---- Make hard iron correction -----------------------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
250 // Measured magnetometer orientation, measured ok
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
251 // From matthias drawing: (X,Y,Z) --> (X,Y,Z) : no rotation
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
252 iBpx = compass_DX_f - compass_CX_f; // X
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
253 iBpy = compass_DY_f - compass_CY_f; // Y
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
254 iBpz = compass_DZ_f - compass_CZ_f; // Z
0
heinrichsweikamp
parents:
diff changeset
255
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
256 //---- Calculate sine and cosine of roll angle Phi -----------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
257 sincos(accel_DZ_f, accel_DY_f, &sin, &cos);
650
bc214815deb2 3.19/10.75 release
heinrichsweikamp
parents: 628
diff changeset
258
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
259 //---- rotate by roll angle (-Phi) ---------------------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
260 iBfy = imul(iBpy, cos) - imul(iBpz, sin);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
261 iBpz = imul(iBpy, sin) + imul(iBpz, cos);
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
262 Gz = imul(accel_DY_f, sin) + imul(accel_DZ_f, cos);
0
heinrichsweikamp
parents:
diff changeset
263
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
264 //---- calculate sin and cosine of pitch angle Theta ---------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
265 sincos(Gz, -accel_DX_f, &sin, &cos); // NOTE: changed sin sign
628
cd58f7fc86db 3.05 stable work
heinrichsweikamp
parents: 623
diff changeset
266
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
267 /* correct cosine if pitch not in range -90 to 90 degrees */
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
268 if( cos < 0 ) cos = -cos;
0
heinrichsweikamp
parents:
diff changeset
269
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
270 ///---- de-rotate by pitch angle Theta -----------------------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
271 iBfx = imul(iBpx, cos) + imul(iBpz, sin);
0
heinrichsweikamp
parents:
diff changeset
272
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
273 //---- calculate current yaw = e-compass angle Psi -----------------------
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
274 // Result in degree (no need of 0.01 deg precision...
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
275 compass_heading_new = itan(-iBfy, iBfx) / 100;
0
heinrichsweikamp
parents:
diff changeset
276
604
ca4556fb60b9 bump to 2.99beta, work on 3.00 stable
heinrichsweikamp
parents: 282
diff changeset
277 // Result in 0..360 range:
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
278 if( compass_heading_new < 0 )
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
279 compass_heading_new += 360;
0
heinrichsweikamp
parents:
diff changeset
280 }
623
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
281
c40025d8e750 3.03 beta released
heinrichsweikamp
parents: 621
diff changeset
282 #endif // _compass