forked from AeroQuad/AeroQuad
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAeroQuad.h
425 lines (382 loc) · 13.1 KB
/
AeroQuad.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
/*
AeroQuad v2.5 Beta 1 - July 2011
www.AeroQuad.com
Copyright (c) 2011 Ted Carancho. All rights reserved.
An Open Source Arduino based multicopter.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#include "WProgram.h"
#include "pins_arduino.h"
// Flight Software Version
#define VERSION 2.5
#define BAUD 115200
//#define BAUD 111111 // use this to be compatible with USB and XBee connections
//#define BAUD 57600
#define LEDPIN 13
#define ON 1
#define OFF 0
#if defined(APM_OP_CHR6DM) || defined(ArduCopter)
#define LED_Red 35
#define LED_Yellow 36
#define LED_Green 37
#define RELE_pin 47
#define SW1_pin 41
#define SW2_pin 40
#define BUZZER 9
#define PIANO_SW1 42
#define PIANO_SW2 43
#endif
#ifdef AeroQuadMega_v2
#define LED2PIN 4
#define LED3PIN 31
#else
#define LED2PIN 12
#define LED3PIN 12
#endif
// Basic axis definitions
#define ROLL 0
#define PITCH 1
#define YAW 2
#define THROTTLE 3
#define MODE 4
#define AUX 5
#define AUX2 6
#define AUX3 7
#define XAXIS 0
#define YAXIS 1
#define ZAXIS 2
#define LASTAXIS 3
#define LEVELROLL 3
#define LEVELPITCH 4
#define LASTLEVELAXIS 5
#define HEADING 5
#define LEVELGYROROLL 6
#define LEVELGYROPITCH 7
#define ALTITUDE 8
#define ZDAMPENING 9
// PID Variables
struct PIDdata {
float P, I, D;
float lastPosition;
// AKA experiments with PID
float previousPIDTime;
bool firstPass;
bool typePID;
float integratedError;
float windupGuard; // Thinking about having individual wind up guards for each PID
} PID[10];
// This struct above declares the variable PID[] to hold each of the PID values for various functions
// The following constants are declared in AeroQuad.h
// ROLL = 0, PITCH = 1, YAW = 2 (used for Arcobatic Mode, gyros only)
// ROLLLEVEL = 3, PITCHLEVEL = 4, LEVELGYROROLL = 6, LEVELGYROPITCH = 7 (used for Stable Mode, accels + gyros)
// HEADING = 5 (used for heading hold)
// ALTITUDE = 8 (used for altitude hold)
// ZDAMPENING = 9 (used in altitude hold to dampen vertical accelerations)
float windupGuard; // Read in from EEPROM
// PID types
#define NOTYPE 0
#define TYPEPI 1
// Smoothing filter parameters
#define GYRO 0
#define ACCEL 1
#define FINDZERO 49
float smoothHeading;
// Sensor pin assignments
#define PITCHACCELPIN 0
#define ROLLACCELPIN 1
#define ZACCELPIN 2
#define PITCHRATEPIN 3
#define ROLLRATEPIN 4
#define YAWRATEPIN 5
#define AZPIN 12 // Auto zero pin for IDG500 gyros
// Motor control variables
#define FRONT 0
#define REAR 1
#define RIGHT 2
#define LEFT 3
#define MOTORID1 0
#define MOTORID2 1
#define MOTORID3 2
#define MOTORID4 3
#define MOTORID5 4
#define MOTORID6 5
#define MINCOMMAND 1000
#define MAXCOMMAND 2000
#if defined(plusConfig) || defined(XConfig)
#define LASTMOTOR 4
#endif
#if defined(HEXACOAXIAL) || defined(HEXARADIAL)
#define LASTMOTOR 6
#endif
// Analog Reference Value
// This value provided from Configurator
// Use a DMM to measure the voltage between AREF and GND
// Enter the measured voltage below to define your value for aref
// If you don't have a DMM use the following:
// AeroQuad Shield v1.7, aref = 3.0
// AeroQuad Shield v1.6 or below, aref = 2.8
float aref; // Read in from EEPROM
// Flight Mode
#define ACRO 0
#define STABLE 1
byte flightMode;
unsigned long frameCounter = 0; // main loop executive frame counter
int minAcro; // Read in from EEPROM, defines min throttle during flips
#define PWM2RAD 0.002 // Based upon 5RAD for full stick movement, you take this times the RAD to get the PWM conversion factor
// Auto level setup
//float levelAdjust[2] = {0.0,0.0};
//int levelAdjust[2] = {0,0};
//int levelLimit; // Read in from EEPROM
//int levelOff; // Read in from EEPROM
// Scale to convert 1000-2000 PWM to +/- 45 degrees
//float mLevelTransmitter = 0.09;
//float bLevelTransmitter = -135;
#if defined(AeroQuadMega_CHR6DM) || defined(APM_OP_CHR6DM)
float CHR_RollAngle;
float CHR_PitchAngle;
#endif
// Heading hold
byte headingHoldConfig;
//float headingScaleFactor;
float commandedYaw = 0;
float headingHold = 0; // calculated adjustment for quad to go to heading (PID output)
float heading = 0; // measured heading from yaw gyro (process variable)
float relativeHeading = 0; // current heading the quad is set to (set point)
#if defined(AeroQuadMega_CHR6DM) || defined(APM_OP_CHR6DM)
float absoluteHeading = 0;;
#endif
float setHeading = 0;
unsigned long headingTime = micros();
byte headingHoldState = OFF;
// batteryMonitor & Altutude Hold
int throttle = 1000;
int autoDescent = 0;
// Altitude Hold
#define ALTPANIC 2 // special state that allows immediate turn off of Altitude hold if large throttle changesa are made at the TX
#define ALTBUMP 90 // amount of stick movement to cause an altutude bump (up or down)
#define PANICSTICK_MOVEMENT 250 // 80 if althold on and throttle commanded to move by a gross amount, set PANIC
//#define MINSTICK_MOVEMENT 32 // any movement less than this doesn't not trigger a rest of the holdaltitude
#define TEMPERATURE 0
#define PRESSURE 1
int throttleAdjust = 0;
int minThrottleAdjust = -50;
int maxThrottleAdjust = 50;
float holdAltitude = 0.0;
int holdThrottle = 1000;
float zDampening = 0.0;
byte storeAltitude = OFF;
byte altitudeHold = OFF;
// Receiver variables
#define TIMEOUT 25000
#define MINCOMMAND 1000
#define MIDCOMMAND 1500
#define MAXCOMMAND 2000
#define MINDELTA 200
#define MINCHECK MINCOMMAND + 100
#define MAXCHECK MAXCOMMAND - 100
#define MINTHROTTLE MINCOMMAND + 100
#define LEVELOFF 100
int delta;
#define RISING_EDGE 1
#define FALLING_EDGE 0
#define MINONWIDTH 950
#define MAXONWIDTH 2075
#define MINOFFWIDTH 12000
#define MAXOFFWIDTH 24000
// Flight angle variables
float timeConstant;
// ESC Calibration
byte calibrateESC = 0;
int testCommand = 1000;
// Communication
char queryType = 'X';
byte tlmType = 0;
byte armed = OFF;
byte safetyCheck = OFF;
byte update = 0;
HardwareSerial *binaryPort;
/**************************************************************/
/******************* Loop timing parameters *******************/
/**************************************************************/
/*
#define RECEIVERLOOPTIME 100000 // 100ms, 10Hz
#define COMPASSLOOPTIME 103000 // 103ms, ~10Hz
#define ALTITUDELOOPTIME 50000 // 50ms x 2, 10Hz (alternates between temperature and pressure measurements)
#define BATTERYLOOPTIME 100000 // 100ms, 10Hz
#define CAMERALOOPTIME 20000 // 20ms, 50Hz
#define FASTTELEMETRYTIME 15000 // 15ms, 67Hz
#define TELEMETRYLOOPTIME 100000 // 100ms, 10Hz for slower computers/cables (more rough Configurator values)
*/
float G_Dt = 0.002;
// Offset starting times so that events don't happen at the same time
// main loop times
unsigned long previousTime = 0;
unsigned long currentTime = 0;
unsigned long deltaTime = 0;
// sub loop times
//unsigned long oneHZpreviousTime;
unsigned long tenHZpreviousTime;
unsigned long twentyFiveHZpreviousTime;
unsigned long fiftyHZpreviousTime;
unsigned long hundredHZpreviousTime;
// old times.
//unsigned long receiverTime = 0;
//unsigned long compassTime = 5000;
//unsigned long altitudeTime = 10000;
//unsigned long batteryTime = 15000;
//unsigned long autoZeroGyroTime = 0;
#ifdef CameraControl
unsigned long cameraTime = 10000;
#endif
unsigned long fastTelemetryTime = 0;
//unsigned long telemetryTime = 50000; // make telemetry output 50ms offset from receiver check
// jihlein: wireless telemetry defines
/**************************************************************/
/********************** Wireless Telem Port *******************/
/**************************************************************/
#if defined WirelessTelemetry && (defined(AeroQuadMega_v1) || \
defined(AeroQuadMega_v2) || \
defined(AeroQuadMega_Wii) || \
defined(ArduCopter) || \
defined(AeroQuadMega_CHR6DM) || \
defined(APM_OP_CHR6DM))
#define SERIAL_BAUD 115200
#define SERIAL_PRINT Serial3.print
#define SERIAL_PRINTLN Serial3.println
#define SERIAL_AVAILABLE Serial3.available
#define SERIAL_READ Serial3.read
#define SERIAL_FLUSH Serial3.flush
#define SERIAL_BEGIN Serial3.begin
#else
#define SERIAL_BAUD 115200
#define SERIAL_PRINT Serial.print
#define SERIAL_PRINTLN Serial.println
#define SERIAL_AVAILABLE Serial.available
#define SERIAL_READ Serial.read
#define SERIAL_FLUSH Serial.flush
#define SERIAL_BEGIN Serial.begin
#endif
/**************************************************************/
/********************** Debug Parameters **********************/
/**************************************************************/
// Enable/disable control loops for debug
//#define DEBUG
byte receiverLoop = ON;
byte telemetryLoop = ON;
byte sensorLoop = ON;
byte controlLoop = ON;
#ifdef CameraControl
byte cameraLoop = ON; // Note: stabilization camera software is still under development, moved to Arduino Mega
#endif
byte fastTransfer = OFF; // Used for troubleshooting
byte testSignal = LOW;
// **************************************************************
// *************************** EEPROM ***************************
// **************************************************************
// EEPROM storage addresses
typedef struct {
float p;
float i;
float d;
} t_NVR_PID;
typedef struct {
float slope;
float offset;
float smooth_factor;
} t_NVR_Receiver;
typedef struct {
t_NVR_PID ROLL_PID_GAIN_ADR;
t_NVR_PID LEVELROLL_PID_GAIN_ADR;
t_NVR_PID YAW_PID_GAIN_ADR;
t_NVR_PID PITCH_PID_GAIN_ADR;
t_NVR_PID LEVELPITCH_PID_GAIN_ADR;
t_NVR_PID HEADING_PID_GAIN_ADR;
t_NVR_PID LEVEL_GYRO_ROLL_PID_GAIN_ADR;
t_NVR_PID LEVEL_GYRO_PITCH_PID_GAIN_ADR;
t_NVR_PID ALTITUDE_PID_GAIN_ADR;
t_NVR_PID ZDAMP_PID_GAIN_ADR;
t_NVR_Receiver RECEIVER_DATA[LASTCHANNEL];
float WINDUPGUARD_ADR;
float XMITFACTOR_ADR;
float GYROSMOOTH_ADR;
float ACCSMOOTH_ADR;
float LEVELPITCHCAL_ADR;
float LEVELROLLCAL_ADR;
float LEVELZCAL_ADR;
float FILTERTERM_ADR;
float HEADINGSMOOTH_ADR;
float AREF_ADR;
float FLIGHTMODE_ADR;
float HEADINGHOLD_ADR;
float MINACRO_ADR;
float ACCEL1G_ADR;
// float ALTITUDE_PGAIN_ADR;
float ALTITUDE_MAX_THROTTLE_ADR;
float ALTITUDE_MIN_THROTTLE_ADR;
float ALTITUDE_SMOOTH_ADR;
// float ZDAMP_PGAIN_ADR;
float ALTITUDE_WINDUP_ADR;
float MAGXMAX_ADR;
float MAGXMIN_ADR;
float MAGYMAX_ADR;
float MAGYMIN_ADR;
float MAGZMAX_ADR;
float MAGZMIN_ADR;
float SERVOMINPITCH_ADR;
float SERVOMINROLL_ADR;
float GYRO_ROLL_ZERO_ADR;
float GYRO_PITCH_ZERO_ADR;
float GYRO_YAW_ZERO_ADR;
} t_NVR_Data;
float nvrReadFloat(int address); // defined in DataStorage.h
void nvrWriteFloat(float value, int address); // defined in DataStorage.h
void nvrReadPID(unsigned char IDPid, unsigned int IDEeprom);
void nvrWritePID(unsigned char IDPid, unsigned int IDEeprom);
#define GET_NVR_OFFSET(param) ((int)&(((t_NVR_Data*) 0)->param))
#define readFloat(addr) nvrReadFloat(GET_NVR_OFFSET(addr))
#define writeFloat(value, addr) nvrWriteFloat(value, GET_NVR_OFFSET(addr))
#define readPID(IDPid, addr) nvrReadPID(IDPid, GET_NVR_OFFSET(addr))
#define writePID(IDPid, addr) nvrWritePID(IDPid, GET_NVR_OFFSET(addr))
// external dunction defined
float arctan2(float y, float x); // defined in AQMath.h
void readEEPROM(void); // defined in DataStorage.h
void readPilotCommands(void); // defined in FlightCommand.pde
void readSensors(void); // defined in Sensors.pde
void processFlightControlXMode(void); // defined in FlightControl.pde
void processFlightControlPlusMode(void); // defined in FlightControl.pde
void readSerialCommand(void); //defined in SerialCom.pde
void sendSerialTelemetry(void); // defined in SerialCom.pde
void printInt(int data); // defined in SerialCom.pde
float readFloatSerial(void); // defined in SerialCom.pde
void sendBinaryFloat(float); // defined in SerialCom.pde
void sendBinaryuslong(unsigned long); // defined in SerialCom.pde
void fastTelemetry(void); // defined in SerialCom.pde
void comma(void); // defined in SerialCom.pde
void processAltitudeHold(void); // defined in FlightControl.pde
#if defined(AeroQuadMega_CHR6DM) || defined(APM_OP_CHR6DM)
float findMode(float *data, int arraySize); // defined in Sensors.pde
#else
int findMode(int *data, int arraySize); // defined in Sensors.pde
#endif
// FUNCTION: return the number of bytes currently free in RAM
extern int __bss_end; // used by freemem
extern int *__brkval; // used by freemem
int freemem(){
int free_memory;
if((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}