Rev 2160 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2160 | Rev 2189 | ||
---|---|---|---|
Line 4... | Line 4... | ||
4 | 4 | ||
5 | #ifndef _ATTITUDE_H |
5 | #ifndef _ATTITUDE_H |
Line 6... | Line 6... | ||
6 | #define _ATTITUDE_H |
6 | #define _ATTITUDE_H |
- | 7 | ||
Line 7... | Line 8... | ||
7 | 8 | #include <inttypes.h> |
|
8 | #include <inttypes.h> |
9 | #include <math.h> |
- | 10 | ||
Line 9... | Line -... | ||
9 | - | ||
10 | #include "analog.h" |
- | |
11 | #include "timer0.h" |
- | |
12 | - | ||
13 | /* |
- | |
14 | * If you have no acc. sensor or do not want to use it, remove this define. This will cause the |
- | |
15 | * acc. sensor to be ignored at attitude calibration. |
- | |
16 | */ |
- | |
17 | #define ATTITUDE_USE_ACC_SENSORS yes |
- | |
18 | - | ||
19 | /* |
- | |
20 | * Default hysteresis to use for the -180 degree to 180 degree wrap. |
- | |
21 | */ |
- | |
22 | #define PITCHOVER_HYSTERESIS 0L |
- | |
23 | #define ROLLOVER_HYSTERESIS 0L |
- | |
24 | - | ||
25 | /* |
- | |
26 | * The frequency at which numerical integration takes place. 488 in original code. |
- | |
27 | */ |
- | |
28 | #define INTEGRATION_FREQUENCY F_MAINLOOP |
- | |
29 | - | ||
30 | /* |
- | |
31 | * Gyro readings are divided by this before being used in attitude control. This will scale them |
11 | #include "analog.h" |
32 | * to match the scale of the stick control etc. variables. This is just a rough non-precision |
- | |
33 | * scaling - the below definitions make precise conversion factors. |
- | |
34 | */ |
- | |
35 | #define HIRES_GYRO_INTEGRATION_FACTOR 1 |
- | |
36 | // (int)((GYRO_RATE_FACTOR_PITCHROLL * INTEGRATION_FREQUENCY * GYRO_PITCHROLL_CORRECTION) / 1250) |
- | |
37 | - | ||
38 | /* |
- | |
39 | Gyro integration: |
- | |
40 | - | ||
41 | The control loop executes at INTEGRATION_FREQUENCY Hz, and for each iteration |
- | |
42 | gyro_ATT[PITCH/ROLL] is added to gyroIntegral[PITCH/ROLL]. |
- | |
43 | Assuming a constant rotation rate v and a zero initial gyroIntegral |
- | |
44 | (for this explanation), we get: |
- | |
45 | - | ||
46 | gyroIntegral = |
- | |
47 | t * INTEGRATION_FREQUENCY * v * GYRO_RATE_FACTOR_PITCHROLL / HIRES_GYRO_INTEGRATION_FACTOR |
- | |
48 | - | ||
49 | For one degree of rotation: t*v = 1: |
- | |
50 | - | ||
51 | gyroIntegral = INTEGRATION_FREQUENCY * v * GYRO_RATE_FACTOR_PITCHROLL / HIRES_GYRO_INTEGRATION_FACTOR |
- | |
52 | - | ||
53 | This number (INTEGRATION_FREQUENCY * v * GYRO_RATE_FACTOR_PITCHROLL / HIRES_GYRO_INTEGRATION_FACTOR) is the integral-to-degree factor. |
- | |
54 | - | ||
55 | Examples: |
- | |
56 | FC1.3: GYRO_DEG_FACTOR_PITCHROLL = 2545 |
- | |
57 | FC2.0: GYRO_DEG_FACTOR_PITCHROLL = 2399 |
- | |
58 | My InvenSense copter: GYRO_DEG_FACTOR_PITCHROLL = 1333 |
- | |
59 | */ |
- | |
60 | //#define GYRO_PITCHROLL_CORRECTION GYRO_PITCHROLL_CORRECTION_should_be_overridden_with_a_-D_at_compile_time |
- | |
61 | #define GYRO_DEG_FACTOR_PITCHROLL (uint16_t)(GYRO_RATE_FACTOR_PITCHROLL * INTEGRATION_FREQUENCY * GYRO_PITCHROLL_CORRECTION / HIRES_GYRO_INTEGRATION_FACTOR) |
- | |
62 | #define GYRO_DEG_FACTOR_YAW (uint16_t)(GYRO_RATE_FACTOR_YAW * INTEGRATION_FREQUENCY * GYRO_YAW_CORRECTION) |
- | |
63 | - | ||
64 | /* |
- | |
65 | * Constant for deriving an attitude angle from acceleration measurement. |
- | |
66 | * |
- | |
67 | * The value is derived from the datasheet of the ACC sensor where 5g are scaled to VRef. |
- | |
68 | * 1g is (3V * 1024) / (5 * 3V) = 205 counts. The ADC ISR sums 2 acc. samples to each |
- | |
69 | * [pitch/roll]AxisAcc and thus reads about acc = 410 counts / g. |
- | |
70 | * We approximate a small pitch/roll angle v by assuming that the copter does not accelerate: |
- | |
71 | * In this explanation it is assumed that the ADC values are 0 based, and gravity is included. |
- | |
72 | * The sine of v is the far side / the hypothenusis: |
- | |
73 | * sin v = acc / sqrt(acc^2 + acc_z^2) |
- | |
74 | * Using that v is a small angle, and the near side is about equal to the the hypothenusis: |
- | |
75 | * sin v ~= acc / acc_z |
- | |
76 | * Assuming that the multicopter is hovering at small pitch and roll angles, acc_z is about 410, |
- | |
77 | * and sin v ~= v (small angles, in radians): |
- | |
78 | * sin v ~= acc / 410 |
- | |
79 | * v / 57.3 ~= acc / 410 |
- | |
80 | * v ~= acc * 57.3 / 410 |
- | |
81 | * acc / v ~= 410 / 57.3 ~= 7, that is: There are about 7 counts per degree. |
- | |
Line 82... | Line -... | ||
82 | * |
- | |
83 | * Summary: DEG_ACC_FACTOR = (2 * 1024 * [sensitivity of acc. meter in V/g]) / (3V * 57.3) |
- | |
84 | */ |
- | |
85 | #define DEG_ACC_FACTOR 7 |
- | |
86 | - | ||
87 | - | ||
88 | /* |
12 | //#include "timer0.h" |
89 | * This is ([gyro integral value] / degree) / (degree / acc. sensor value) = gyro integral value / acc.sensor value |
- | |
90 | * = the factor an acc. sensor should be multiplied by to get the gyro integral |
- | |
91 | * value for the same (small) angle. |
- | |
92 | * The value is about 200. |
- | |
93 | */ |
- | |
94 | #define GYRO_ACC_FACTOR ((GYRO_DEG_FACTOR_PITCHROLL) / (DEG_ACC_FACTOR)) |
13 | //#define _PI 3.1415926535897932384626433832795 |
95 | - | ||
96 | #define PITCHROLLOVER180 (GYRO_DEG_FACTOR_PITCHROLL * 180L) |
- | |
97 | #define PITCHROLLOVER360 (GYRO_DEG_FACTOR_PITCHROLL * 360L) |
- | |
98 | #define YAWOVER180 (GYRO_DEG_FACTOR_YAW * 180L) |
- | |
99 | #define YAWOVER360 (GYRO_DEG_FACTOR_YAW * 360L) |
- | |
100 | - | ||
Line 101... | Line 14... | ||
101 | /* |
14 | |
102 | * Rotation rates |
15 | #define ACC_MS2_FACTOR (1.0f / ACC_G_FACTOR_XY) |
103 | */ |
16 | |
104 | extern int16_t rate_PID[2], rate_ATT[2], yawRate; |
17 | // 57.3 |
105 | extern int16_t differential[2]; |
- | |
106 | - | ||
107 | /* |
- | |
108 | * Attitudes calculated by numerical integration of gyro rates |
- | |
109 | */ |
- | |
110 | extern int32_t attitude[2]; |
- | |
111 | - | ||
112 | // This is really a flight module thing, but it should be corrected along |
- | |
113 | // when the yaw angle is corrected from the compass, and that happens here. |
- | |
114 | // extern int32_t yawAngleDiff; |
- | |
115 | - | ||
116 | /* |
- | |
117 | * Compass navigation |
- | |
118 | */ |
- | |
119 | extern int32_t heading; |
- | |
120 | extern uint16_t ignoreCompassTimer; |
- | |
121 | extern uint16_t accVector; |
- | |
122 | - | ||
123 | extern int32_t headingError; |
- | |
124 | - | ||
125 | - | ||
126 | /* |
- | |
127 | * Dynamic gyro offsets. These are signed values that are subtracted from the gyro measurements, |
- | |
128 | * to help canceling out drift and vibration noise effects. The dynamic offsets themselves |
- | |
129 | * can be updated in flight by different ways, for example: |
- | |
130 | * - Just taking them from parameters, so the pilot can trim manually in a PC or mobile tool |
- | |
131 | * - Summing up how much acc. meter correction was done to the gyro integrals over the last n |
- | |
132 | * integration, and then adding the sum / n to the dynamic offset |
- | |
133 | * - Detect which way the pilot pulls the stick to keep the copter steady, and correct by that |
- | |
134 | * - Invent your own... |
- | |
135 | */ |
- | |
Line 136... | Line 18... | ||
136 | extern int16_t dynamicOffset[2], dynamicOffsetYaw; |
18 | #define RAD_DEG_FACTOR (180.0 / M_PI) |
137 | 19 | ||
138 | /* |
20 | /* |
139 | * For NaviCtrl use. |
21 | * Attitudes calculated by numerical integration of gyro rates |
140 | */ |
22 | */ |
Line 141... | Line 23... | ||
141 | extern int16_t averageAcc[2], averageAccCount; |
23 | extern int16_t attitude[3]; |
142 | - | ||
143 | /* |
- | |
144 | * Re-init flight attitude, setting all angles to 0 (or to whatever can be derived from acc. sensor). |
- | |
145 | * To be called when the pilot commands gyro calibration (eg. by moving the left stick up-left or up-right). |
- | |
146 | */ |
- | |
147 | void attitude_setNeutral(void); |
- | |
148 | - | ||
149 | /* |
- | |
150 | * Experiment. |
24 | |
151 | */ |
25 | /* |
152 | // void attitude_startDynamicCalibration(void); |
- | |
153 | // void attitude_continueDynamicCalibration(void); |
- | |
154 | 26 | * Re-init flight attitude, setting all angles to 0 (or to whatever can be derived from acc. sensor). |
|
Line 155... | Line 27... | ||
155 | int32_t getAngleEstimateFromAcc(uint8_t axis); |
27 | * To be called when the pilot commands gyro calibration (eg. by moving the left stick up-left or up-right). |