Subversion Repositories FlightCtrl

Rev

Rev 2048 | Rev 2051 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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