xyControl  0.1
Quadrotor Flight Controller on AVR Basis
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups
orientation.c
Go to the documentation of this file.
1 /*
2  * orientation.c
3  *
4  * Copyright (c) 2013, Thomas Buck <xythobuz@me.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * - Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  *
14  * - Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #include <avr/io.h>
31 #include <stdint.h>
32 #include <math.h>
33 
34 #include <xycontrol.h>
35 #include <error.h>
36 #include <gyro.h>
37 #include <acc.h>
38 #include <mag.h>
39 #include <tasks.h>
40 #include <time.h>
41 #include <orientation.h>
42 #include <kalman.h>
43 #include <complementary.h>
44 #include <config.h>
45 
55 #define TODEG(x) ((x * 180) / M_PI)
58 Angles orientation = {.pitch = 0, .roll = 0, .yaw = 0};
59 
61 Angles orientationError = {.pitch = 0, .roll = 0, .yaw = 0};
62 
63 #if ORIENTATION_FILTER == FILTER_KALMAN
66 #elif ORIENTATION_FILTER == FILTER_COMPLEMENTARY
69 #else
70 #error Define a Filter for the orientation Data
71 #endif
72 
74  Error e = accInit(r4G);
75  CHECKERROR(e);
76  e = gyroInit(r250DPS);
77  CHECKERROR(e);
78 
79 #if ORIENTATION_FILTER == FILTER_KALMAN
80  kalmanInit(&pitchData);
81  kalmanInit(&rollData);
82 #elif ORIENTATION_FILTER == FILTER_COMPLEMENTARY
83  complementaryInit(&pitchData);
84  complementaryInit(&rollData);
85 #endif
86 
87  return SUCCESS;
88 }
89 
91  Vector3f g, a;
92  Error e = accRead(&a); // Read Accelerometer
93  CHECKERROR(e);
94  e = gyroRead(&g); // Read Gyroscope
95  CHECKERROR(e);
96 
97  // Calculate Pitch & Roll from Accelerometer Data
98  double roll = atan(a.x / hypot(a.y, a.z));
99  double pitch = atan(a.y / hypot(a.x, a.z));
100  roll = TODEG(roll);
101  pitch = TODEG(pitch); // As Degree, not radians!
102 
103  // Filter Roll and Pitch with Gyroscope Data from the corresponding axis
104 #if ORIENTATION_FILTER == FILTER_KALMAN
105  kalmanInnovate(&pitchData, pitch, g.x);
106  kalmanInnovate(&rollData, roll, g.y);
107  orientation.roll = rollData.x1;
108  orientation.pitch = pitchData.x1;
109 #elif ORIENTATION_FILTER == FILTER_COMPLEMENTARY
110  complementaryExecute(&pitchData, pitch, g.x);
111  complementaryExecute(&rollData, roll, g.y);
112  orientation.roll = rollData.angle;
113  orientation.pitch = pitchData.angle;
114 #endif
115 
116  // Zero Offset for angles
117  orientation.roll -= orientationError.roll;
118  orientation.pitch -= orientationError.pitch;
119  orientation.yaw -= orientationError.yaw;
120 
121  // Store Angle Speeds
122  orientation.vRoll = g.y;
123  orientation.vPitch = g.x;
124  orientation.vYaw = g.z;
125 
126  // Self-Reset if data is garbage and we just came up
127  if (getSystemTime() < 2000) {
128  if (isnan(orientation.roll) || isnan(orientation.pitch) || isnan(orientation.yaw)) {
129  xySelfReset();
130  return ERROR;
131  }
132  }
133 
134  return SUCCESS;
135 }
136 
137 void zeroOrientation(void) {
138  orientationError.roll = orientation.roll + orientationError.roll;
139  orientationError.pitch = orientation.pitch + orientationError.pitch;
140  orientationError.yaw = orientation.yaw + orientationError.yaw;
141 }