xyControl  0.1
Quadrotor Flight Controller on AVR Basis
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups
uartFlight.c
1 /*
2  * uartFlight.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 <stdint.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <avr/io.h>
34 #include <avr/pgmspace.h>
35 
36 #define DEBUG 1
37 
38 #include <debug.h>
39 #include <tasks.h>
40 #include <error.h>
41 #include <xycontrol.h>
42 #include <time.h>
43 #include <uartMenu.h>
44 #include <serial.h>
45 #include <acc.h>
46 #include <gyro.h>
47 #include <mag.h>
48 #include <motor.h>
49 #include <orientation.h>
50 #include <pid.h>
51 #include <set.h>
52 
55 #define MAXANGLE 45
56 #define ANGLESTEP 10
57 #define MAXMOTOR 255
58 #define MOTORSTEP 10
59 #define QUADFREQ 100
60 #define STATUSFREQ 10
61 
62 #define QUADDELAY (1000 / QUADFREQ)
63 #define STATUSDELAY (1000 / STATUSFREQ)
64 
65 void flightTask(void);
66 void statusTask(void);
67 void controlToggle(void);
68 void motorToggle(void);
69 void motorUp(void);
70 void motorDown(void);
71 void motorForward(void);
72 void motorBackward(void);
73 void motorLeft(void);
74 void motorRight(void);
75 void parameterChange(void);
76 void silent(void);
77 void printRaw(void);
78 
79 char PROGMEM motorToggleString[] = "Motor On/Off";
80 char PROGMEM motorUpString[] = "Up";
81 char PROGMEM motorDownString[] = "Down";
82 char PROGMEM motorLeftString[] = "Left";
83 char PROGMEM motorRightString[] = "Right";
84 char PROGMEM motorForwardString[] = "Forwards";
85 char PROGMEM motorBackwardString[] = "Backwards";
86 char PROGMEM controlToggleString[] = "Toggle PID";
87 char PROGMEM parameterChangeString[] = "Change PID Params";
88 char PROGMEM zeroString[] = "Angles to Zero";
89 char PROGMEM silentString[] = "Toggle Status Output";
90 char PROGMEM sensorString[] = "Raw Sensor Data";
91 
92 #define STATE_MOTOR (1 << 0) // 1 -> Motor On
93 #define STATE_PID (1 << 1) // 1 -> PID enabled
94 #define STATE_OUTPUT (1 << 2) // 1 -> No Status Output
95 uint8_t state = 0;
96 
97 uint8_t speed = 10;
98 int16_t targetRoll = 0;
99 int16_t targetPitch = 0;
100 
101 uint32_t sumFlightTask = 0, countFlightTask = 0;
102 
103 int main(void) {
104  xyInit();
105  pidInit();
106  motorInit();
107  orientationInit();
108 
109  debugPrint("Initialized Hardware");
110 
111  addTask(&flightTask);
112  addTask(&statusTask);
113 
114  addMenuCommand('m', motorToggleString, &motorToggle);
115  addMenuCommand('w', motorForwardString, &motorForward);
116  addMenuCommand('a', motorLeftString, &motorLeft);
117  addMenuCommand('s', motorBackwardString, &motorBackward);
118  addMenuCommand('d', motorRightString, &motorRight);
119  addMenuCommand('x', motorUpString, &motorUp);
120  addMenuCommand('y', motorDownString, &motorDown);
121  addMenuCommand('p', controlToggleString, &controlToggle);
122  addMenuCommand('n', parameterChangeString, &parameterChange);
123  addMenuCommand('z', zeroString, &zeroOrientation);
124  addMenuCommand('o', silentString, &silent);
125  addMenuCommand('r', sensorString, &printRaw);
126 
129 
130  debugPrint("Starting Tasks");
131 
132  for(;;) {
133  tasks();
134  }
135 
136  return 0;
137 }
138 
139 void flightTask(void) {
140  static time_t last = 100; // Don't begin immediately
141  if ((getSystemTime() - last) >= QUADDELAY) {
142  last = getSystemTime();
143  Error e = orientationTask();
144  REPORTERROR(e);
145  if (state & STATE_PID) {
146  pidTask();
147  } else {
148  pidOutput[0] = pidOutput[1] = 0;
149  }
150  setTask();
151  motorTask();
152 
153  uint32_t diff = getSystemTime() - last;
154  if (++countFlightTask >= QUADFREQ) {
155  countFlightTask = 1;
156  sumFlightTask = diff;
157  } else {
158  sumFlightTask += diff;
159  }
160  }
161 }
162 
163 void statusTask(void) {
164  static time_t last = 100; // Don't begin immediately
165  static uint32_t lastDuration = 0;
166  if (((getSystemTime() - last) >= STATUSDELAY) && (!(state & STATE_OUTPUT))) {
167  last = getSystemTime();
168  printf("p%.2f %.2f %.2f\n", orientation.vPitch, orientation.vRoll, orientation.vYaw);
169  printf("q%li %li\n", sumFlightTask / countFlightTask, lastDuration);
170  printf("r%.2f %.2f\n", pidStates[0].intMin, pidStates[0].intMax);
171  printf("s%.2f %.2f\n", pidStates[0].outMin, pidStates[0].outMax);
172  printf("t%.3f %.3f %.3f\n", pidStates[0].kp, pidStates[0].ki, pidStates[0].kd);
173  printf("u%.2f %.2f\n", pidOutput[PITCH], pidOutput[ROLL]);
174  printf("v%i %i %i %i\n", motorSpeed[0], motorSpeed[1], motorSpeed[2], motorSpeed[3]);
175  printf("w%.2f\n", orientation.pitch);
176  printf("x%.2f\n", orientation.roll);
177  printf("y%.2f\n", orientation.yaw);
178  printf("z%.2f\n", getVoltage());
179  lastDuration = getSystemTime() - last;
180  }
181 }
182 
183 void controlToggle(void) {
184  if (state & STATE_PID) {
185  state &= ~STATE_PID;
186  printf("PID Off!\n");
187  } else {
188  state |= STATE_PID;
189  printf("PID On!\n");
190  }
191 }
192 
193 void motorToggle(void) {
194  if (state & STATE_MOTOR) {
195  state &= ~STATE_MOTOR;
196  baseSpeed = 0;
197  printf("Motor Off!\n");
198  } else {
199  state |= STATE_MOTOR;
200  baseSpeed = speed = 10;
201  printf("Motor On!\n");
202  }
203 }
204 
205 void motorUp(void) {
206  if (speed <= (MAXMOTOR - MOTORSTEP)) {
207  if (state & STATE_MOTOR) {
208  speed += MOTORSTEP;
209  baseSpeed = speed;
210  printf("Throttle up to %i\n", speed);
211  }
212  }
213 }
214 
215 void motorDown(void) {
216  if (speed >= MOTORSTEP) {
217  if (state & STATE_MOTOR) {
218  speed -= MOTORSTEP;
219  baseSpeed = speed;
220  printf("Throttle down to %i\n", speed);
221  }
222  }
223 }
224 
225 void motorForward(void) {
226  if (targetPitch >= (-1 * (MAXANGLE - ANGLESTEP))) {
227  targetPitch -= ANGLESTEP;
228  pidTarget[PITCH] = targetPitch;
229  printf("Pitch Forward %i\n", targetPitch);
230  }
231 }
232 
233 void motorBackward(void) {
234  if (targetPitch <= (MAXANGLE - ANGLESTEP)) {
235  targetPitch += ANGLESTEP;
236  pidTarget[PITCH] = targetPitch;
237  printf("Pitch Backwards %i\n", targetPitch);
238  }
239 }
240 
241 void motorLeft(void) {
242  if (targetRoll <= (MAXANGLE - ANGLESTEP)) {
243  targetRoll += ANGLESTEP;
244  pidTarget[ROLL] = targetRoll;
245  printf("Roll Left %i\n", targetRoll);
246  }
247 }
248 
249 void motorRight(void) {
250  if (targetRoll >= (-1 * (MAXANGLE - ANGLESTEP))) {
251  targetRoll -= ANGLESTEP;
252  pidTarget[ROLL] = targetRoll;
253  printf("Roll Right %i\n", targetRoll);
254  }
255 }
256 
257 void parameterChange(void) {
258  double p, i, d, min, max, iMin, iMax;
259  int c = scanf("%lf %lf %lf %lf %lf %lf %lf", &p, &i, &d, &min, &max, &iMin, &iMax);
260  if (c == 7) {
261  pidSet(&pidStates[0], p, i, d, min, max, iMin, iMax);
262  pidSet(&pidStates[1], p, i, d, min, max, iMin, iMax);
263  } else {
264  printf("Only got %i (%lf %lf %lf %lf %lf %lf %lf)!\n", c, p, i, d, min, max, iMin, iMax);
265  }
266 }
267 
268 void silent(void) {
269  if (state & STATE_OUTPUT) {
270  // Currently disabled, bit set
271  state &= ~STATE_OUTPUT; // Unset Bit
272  } else {
273  // Currently enabled
274  state |= STATE_OUTPUT; // Set Bit
275  }
276 }
277 
278 void printRaw(void) {
279  Vector3f v;
280  accRead(&v);
281  printf("Ax: %f Ay: %f Az: %f\n", v.x, v.y, v.z);
282  gyroRead(&v);
283  printf("Gx: %f Gy: %f Gz: %f\n", v.x, v.y, v.z);
284  magRead(&v);
285  printf("Mx: %f My: %f Mz: %f\n", v.x, v.y, v.z);
286 }