Subversion Repositories FlightCtrl

Rev

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

Rev Author Line No. Line
1910 - 1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include "eeprom.h"
4
#include "flight.h"
5
#include "output.h"
6
 
7
// Necessary for external control and motor test
8
#include "uart0.h"
9
 
10
// for scope debugging
11
// #include "rc.h"
12
 
13
#include "timer2.h"
14
#include "attitude.h"
15
#include "controlMixer.h"
16
#include "commands.h"
17
#ifdef USE_MK3MAG
18
#include "gps.h"
19
#endif
20
 
21
#define CHECK_MIN_MAX(value, min, max) {if(value < min) value = min; else if(value > max) value = max;}
22
 
23
/*
24
 * These are no longer maintained, just left at 0. The original implementation just summed the acc.
25
 * value to them every 2 ms. No filtering or anything. Just a case for an eventual overflow?? Hey???
26
 */
27
// int16_t naviAccPitch = 0, naviAccRoll = 0, naviCntAcc = 0;
28
 
29
int8_t pitchPFactor, rollPFactor, yawPFactor;
30
int8_t pitchDFactor, rollDFactor, yawDFactor;
31
 
32
int32_t IPart[2] = {0,0};
33
 
34
/************************************************************************/
35
/*  Filter for motor value smoothing (necessary???)                     */
36
/************************************************************************/
37
int16_t outputFilter(int16_t newvalue, int16_t oldvalue) {
38
  switch (dynamicParams.UserParams[5]) {
39
  case 0:
40
    return newvalue;
41
  case 1:
42
    return (oldvalue + newvalue) / 2;
43
  case 2:
44
    if (newvalue > oldvalue)
45
      return (1 * (int16_t) oldvalue + newvalue) / 2; //mean of old and new
46
    else
47
      return newvalue - (oldvalue - newvalue) * 1; // 2 * new - old
48
  case 3:
49
    if (newvalue < oldvalue)
50
      return (1 * (int16_t) oldvalue + newvalue) / 2; //mean of old and new
51
    else
52
      return newvalue - (oldvalue - newvalue) * 1; // 2 * new - old
53
  default:
54
    return newvalue;
55
  }
56
}
57
 
58
/************************************************************************/
59
/*  Neutral Readings                                                    */
60
/************************************************************************/
61
#define CONTROL_CONFIG_SCALE 10
62
 
63
void flight_setNeutral() {
64
  // not really used here any more.
65
  controlMixer_initVariables();
66
}
67
 
68
void setFlightParameters
69
(
70
 uint8_t _pitchPFactor,
71
 uint8_t _rollPFactor,
72
 uint8_t _yawPFactor,
73
 
74
 uint8_t _pitchDFactor,
75
 uint8_t _rollDFactor,
76
 uint8_t _yawDFactor
77
 ) {
78
  pitchPFactor = _pitchPFactor;
79
  rollPFactor = _rollPFactor;
80
  yawPFactor = _yawPFactor;
81
 
82
  pitchDFactor = _pitchDFactor;
83
  rollDFactor = _rollDFactor;
84
  yawDFactor = _yawDFactor;
85
}
86
 
87
void setNormalFlightParameters(void) {
88
  setFlightParameters
89
    (
90
     dynamicParams.GyroPitchP / CONTROL_CONFIG_SCALE,     // 12 seems good
91
     dynamicParams.GyroRollP / CONTROL_CONFIG_SCALE,      // 9 seems good
92
     dynamicParams.GyroYawP / (CONTROL_CONFIG_SCALE/2),   // 24 seems too little
93
 
94
     dynamicParams.GyroPitchD / CONTROL_CONFIG_SCALE,
95
     dynamicParams.GyroRollD / CONTROL_CONFIG_SCALE,
96
     dynamicParams.GyroYawD / CONTROL_CONFIG_SCALE
97
     );
98
}
99
 
100
void setStableFlightParameters(void) {
101
  setFlightParameters(0, 0, 0, 0, 0, 0);
102
}
103
 
104
/************************************************************************/
105
/*  Main Flight Control                                                 */
106
/************************************************************************/
107
void flight_control(void) {
108
  // Mixer Fractions that are combined for Motor Control
109
  int16_t yawTerm, throttleTerm, term[2];
110
 
111
  // PID controller variables
112
  int16_t PDPart[2], PDPartYaw;
113
 
114
  static int8_t debugDataTimer = 1;
115
 
116
  // High resolution motor values for smoothing of PID motor outputs
117
  static int16_t outputFilters[MAX_OUTPUTS];
118
 
119
  uint8_t i;
120
 
121
  // Fire the main flight attitude calculation, including integration of angles.
122
  // We want that to kick as early as possible, not to delay new AD sampling further.
123
  calculateFlightAttitude();
124
  controlMixer_update();
125
  throttleTerm = control[CONTROL_THROTTLE];
126
 
127
  /************************************************************************/
128
  /* RC-signal is bad                                                     */
129
  /************************************************************************/
130
 
131
  if (controlMixer_getSignalQuality() <= SIGNAL_BAD) { // the rc-frame signal is not received or noisy
132
    RED_ON;
133
    beepRCAlarm();
134
    setStableFlightParameters();
135
  } else {
136
    commands_handleCommands();
137
    setNormalFlightParameters();
138
  }
139
 
140
  /************************************************************************/
141
  /* Calculate control feedback from angle (gyro integral)                */
142
  /* and angular velocity (gyro signal)                                   */
143
  /************************************************************************/
144
  PDPart[PITCH] = ((int32_t) rate_PID[PITCH] * pitchPFactor /
145
                  (256L / CONTROL_SCALING))
146
  + (differential[PITCH] * (int16_t) dynamicParams.GyroPitchD) / 16;
147
 
148
  PDPart[ROLL] = ((int32_t) rate_PID[ROLL] * rollPFactor /
149
                  (256L / CONTROL_SCALING))
150
  + (differential[ROLL] * (int16_t) dynamicParams.GyroRollD) / 16;
151
 
152
  PDPartYaw = (int32_t) (yawRate * 2 * (int32_t) yawPFactor) / (256L / CONTROL_SCALING)
153
  + (differential[YAW] * (int16_t) dynamicParams.GyroYawD) / 16;
154
 
1922 - 155
  /************************************************************************/
156
  /* Stick signals are positive and gyros are negative...                 */
157
  /************************************************************************/
1927 - 158
  IPart[PITCH] = error[PITCH]; // * some factor configurable.
159
  IPart[ROLL] = error[ROLL];
160
    // TODO: Add ipart. Or add/subtract depending, not sure.
2025 - 161
  term[PITCH] = control[CONTROL_ELEVATOR] + (staticParams.servoDirections & SERVO_DIRECTION_ELEVATOR ? PDPart[PITCH] : -PDPart[PITCH]);
162
  term[ROLL] = control[CONTROL_AILERONS] + (staticParams.servoDirections & SERVO_DIRECTION_AILERONS ? PDPart[ROLL] : -PDPart[ROLL]);
163
  yawTerm = control[CONTROL_RUDDER] + (staticParams.servoDirections & SERVO_DIRECTION_RUDDER ? PDPartYaw : -PDPartYaw);
1910 - 164
 
165
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
166
  // Universal Mixer
167
  // Each (pitch, roll, throttle, yaw) term is in the range [0..255 * CONTROL_SCALING].
168
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
169
 
170
  DebugOut.Analog[12] = term[PITCH];
171
  DebugOut.Analog[13] = term[ROLL];
172
  DebugOut.Analog[14] = throttleTerm;
173
  DebugOut.Analog[15] = yawTerm;
174
 
175
  for (i = 0; i < MAX_OUTPUTS; i++) {
176
    int16_t tmp;
177
      if (outputTestActive) {
178
          outputs[i].SetPoint = outputTest[i] * 4;
179
      } else {
180
        // Follow the normal order of servos: Ailerons, elevator, throttle, rudder.
181
        switch(i) {
182
        case 0: tmp = term[ROLL]; break;
183
        case 1: tmp = term[PITCH]; break;
184
        case 2: tmp = throttleTerm - 310; break;
185
        case 3: tmp = yawTerm; break;
186
        default: tmp = 0;
187
        }
188
      outputFilters[i] = outputFilter(tmp, outputFilters[i]);
189
      // Now we scale back down to a 0..255 range.
190
      tmp = outputFilters[i];
191
      outputs[i].SetPoint = tmp;
192
    }
193
  }
194
 
195
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
196
  // Debugging
197
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
198
  if (!(--debugDataTimer)) {
199
    debugDataTimer = 24; // update debug outputs at 488 / 24 = 20.3 Hz.
200
    DebugOut.Analog[0] = (10 * angle[PITCH]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
201
    DebugOut.Analog[1] = (10 * angle[ROLL]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
1927 - 202
      DebugOut.Analog[2] = angle[YAW] / GYRO_DEG_FACTOR_YAW;
1910 - 203
 
204
    DebugOut.Analog[6] = pitchPFactor;
205
    DebugOut.Analog[7] = rollPFactor;
206
    DebugOut.Analog[8] = yawPFactor;
207
    DebugOut.Analog[9] = pitchDFactor;
208
    DebugOut.Analog[10] = rollDFactor;
209
    DebugOut.Analog[11] = yawDFactor;
210
 
1927 - 211
    DebugOut.Analog[18] = (10 * error[PITCH]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
212
    DebugOut.Analog[19] = (10 * error[ROLL]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
1910 - 213
    DebugOut.Analog[22] = (10 * IPart[PITCH]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
214
    DebugOut.Analog[23] = (10 * IPart[ROLL]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
215
  }
216
}