Subversion Repositories FlightCtrl

Rev

Rev 2160 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1775 - 1
#include <inttypes.h>
2
#include "attitude.h"
3
#include "configuration.h"
2189 - 4
#include "definitions.h"
5
#include "debug.h" 
1775 - 6
 
7
#define INTEGRAL_LIMIT 100000
8
 
2069 - 9
#define LATCH_TIME 3
1775 - 10
 
2088 - 11
// This will translate a height value to a target height in centimeters.
12
// Currently: One step is 50 cm and zero is 5 meters below the takeoff altitude. With max. 255 steps the max.
13
// target height is then about 120m.
14
#define HEIGHT_GAIN 50L
15
#define HEIGHT_FORMULA(x) ((x) * HEIGHT_GAIN - 500L)
16
 
2074 - 17
int32_t setHeight;
1775 - 18
int32_t targetHeight;
19
 
2086 - 20
uint16_t hc_testOscPrescaler = 0;
21
uint8_t hc_testOscTimer = 0;
2074 - 22
 
1961 - 23
int32_t maxHeightThisFlight;
1775 - 24
int32_t iHeight;
25
 
26
void HC_setGround(void) {
2033 - 27
  analog_setGround();
1960 - 28
  // This should also happen when height control is enabled in-flight.
2074 - 29
  setHeight = targetHeight = analog_getHeight();
2086 - 30
  hc_testOscTimer = 0;
1961 - 31
  maxHeightThisFlight = 0;
1960 - 32
  iHeight = 0;
1775 - 33
}
34
 
2075 - 35
uint8_t HC_isSwitchOn(void) {
2069 - 36
  return (dynamicParams.heightSetting >= 255/3);
37
}
38
 
2039 - 39
void HC_periodicTask(void) {
2033 - 40
  int32_t height = analog_getHeight();
1960 - 41
  static uint8_t setHeightLatch = 0;
42
 
1961 - 43
  if (height > maxHeightThisFlight)
44
    maxHeightThisFlight = height;
1960 - 45
 
2059 - 46
  // debugOut.analog[25] = dynamicParams.heightSetting;
47
 
1961 - 48
  if (staticParams.bitConfig & CFG_SIMPLE_HC_HOLD_SWITCH) {
2069 - 49
    if (HC_isSwitchOn()) {
1960 - 50
      // Switch is ON
51
      if (setHeightLatch <= LATCH_TIME) {
2069 - 52
        if (setHeightLatch == LATCH_TIME) {
53
          // Freeze the height as target. We want to do this exactly once each time the switch is thrown ON.
2074 - 54
          setHeight = height;
2086 - 55
          hc_testOscTimer = 0;
2071 - 56
          iHeight = 0;
2069 - 57
        }
58
        // Time not yet reached.
59
        setHeightLatch++;
1960 - 60
      }
61
    } else {
62
      // Switch is OFF.
63
      setHeightLatch = 0;
64
    }
65
  } else {
66
    // Switch is not activated; take the "max-height" as the target height.
2189 - 67
    setHeight = (uint16_t) (HEIGHT_FORMULA(dynamicParams.heightSetting));
1960 - 68
  }
69
 
2069 - 70
  /*
1960 - 71
  if (++heightRampingTimer == INTEGRATION_FREQUENCY / 10) {
72
    heightRampingTimer = 0;
1961 - 73
    if (rampedTargetHeight < targetHeight) {
74
      // climbing
75
      if (rampedTargetHeight < targetHeight - staticParams.heightSlewRate) {
76
        rampedTargetHeight += staticParams.heightSlewRate;
77
      } else {
78
        rampedTargetHeight = targetHeight;
79
      }
2026 - 80
    } else {
1961 - 81
      // descending
82
      if (rampedTargetHeight > targetHeight + staticParams.heightSlewRate) {
83
        rampedTargetHeight -= staticParams.heightSlewRate;
84
      } else {
85
        rampedTargetHeight = targetHeight;
86
      }
1960 - 87
    }
88
  }
2069 - 89
  */
2074 - 90
  //      uint8_t heightControlTestOscPeriod;
91
  //      uint8_t heightControlTestOscAmplitude;
1970 - 92
 
2086 - 93
  hc_testOscPrescaler++;
2189 - 94
 
95
  if (hc_testOscPrescaler == 250) {
2086 - 96
          hc_testOscPrescaler = 0;
97
          hc_testOscTimer++;
98
          if (hc_testOscTimer == staticParams.heightControlTestOscPeriod) {
99
                  hc_testOscTimer = 0;
2079 - 100
                  if (staticParams.heightControlTestOscAmplitude)
101
                          iHeight = 0;
2086 - 102
          } else if (hc_testOscTimer == staticParams.heightControlTestOscPeriod/2) {
2079 - 103
                  if (staticParams.heightControlTestOscAmplitude)
104
                          iHeight = 0;
2074 - 105
          }
106
  }
107
 
2086 - 108
  if (hc_testOscTimer < staticParams.heightControlTestOscPeriod/2)
2074 - 109
          targetHeight = setHeight;
110
  else
2088 - 111
          targetHeight = setHeight + (uint16_t)staticParams.heightControlTestOscAmplitude * HEIGHT_GAIN;
2074 - 112
 
113
  //if (staticParams.)
1960 - 114
  // height, in meters (so the division factor is: 100)
2059 - 115
  // debugOut.analog[24] = (117100 - filteredAirPressure) / 100;
1971 - 116
  // Calculated 0 alt number: 108205
1980 - 117
  // Experimental 0 alt number: 117100
1775 - 118
}
119
 
2074 - 120
#define LOG_PHEIGHT_SCALE 10
121
#define LOG_IHEIGHT_SCALE 24
122
#define LOG_DHEIGHT_SCALE 6
123
 
1775 - 124
// takes 180-200 usec (with integral term). That is too heavy!!!
125
// takes 100 usec without integral term.
2189 - 126
void HC_periodicTaskAndRPTY(int16_t* RPTY) {
2048 - 127
  HC_periodicTask();
2189 - 128
  int16_t throttle = RPTY[CONTROL_THROTTLE];
2033 - 129
  int32_t height = analog_getHeight();
2073 - 130
  int32_t heightError = targetHeight - height;
2033 - 131
  int16_t dHeight = analog_getDHeight();
1960 - 132
 
2058 - 133
  debugOut.analog[22] = height/10L;
134
  debugOut.analog[23] = dHeight;
2055 - 135
 
2026 - 136
  if (heightError > 0) {
1960 - 137
    debugOut.digital[0] |= DEBUG_HEIGHT_DIFF;
2035 - 138
  } else {
1961 - 139
    debugOut.digital[0] &= ~DEBUG_HEIGHT_DIFF;
2035 - 140
  }
141
 
142
  if (dHeight > 0) {
1960 - 143
    debugOut.digital[1] |= DEBUG_HEIGHT_DIFF;
2035 - 144
  } else {
145
    debugOut.digital[1] &= ~DEBUG_HEIGHT_DIFF;
1960 - 146
  }
2032 - 147
 
2073 - 148
  int32_t heightErrorForIntegral = heightError;
2074 - 149
  int32_t heightErrorForIntegralLimit = staticParams.heightControlMaxIntegralIn << LOG_PHEIGHT_SCALE;
2073 - 150
 
151
  if (heightErrorForIntegral > heightErrorForIntegralLimit) {
152
    heightErrorForIntegral = heightErrorForIntegralLimit;
153
  } else if (heightErrorForIntegral < -heightErrorForIntegralLimit) {
154
    heightErrorForIntegral =- heightErrorForIntegralLimit;
155
  }
156
 
2033 - 157
  // iHeight, at a difference of 5 meters and a freq. of 488 Hz, will grow with 244000 / sec....
2073 - 158
  iHeight += heightErrorForIntegral;
2032 - 159
 
2033 - 160
#define IHEIGHT_SCALE 24
161
  // dThrottle is in the range between +/- 1<<(IHEIGHT_SCALE+8)>>(IHEIGHT_SCALE) = +/- 256
2035 - 162
  int16_t dThrottleI =  (iHeight * (int32_t)dynamicParams.heightI) >> (IHEIGHT_SCALE);
2033 - 163
 
2073 - 164
  if (dThrottleI > staticParams.heightControlMaxIntegralOut) {
165
    dThrottleI = staticParams.heightControlMaxIntegralOut;
166
    iHeight = ((int32_t)staticParams.heightControlMaxIntegralOut << IHEIGHT_SCALE) / dynamicParams.heightI;
167
  } else if (dThrottleI < -staticParams.heightControlMaxIntegralOut) {
168
    dThrottleI = -staticParams.heightControlMaxIntegralOut;
169
    iHeight = -((int32_t)staticParams.heightControlMaxIntegralOut << IHEIGHT_SCALE) / dynamicParams.heightI;
2033 - 170
  }
171
 
2074 - 172
  int16_t dThrottleP = (heightError * dynamicParams.heightP) >> LOG_PHEIGHT_SCALE;
173
  int16_t dThrottleD = (dHeight * dynamicParams.heightD) >> LOG_DHEIGHT_SCALE;
2033 - 174
 
2160 - 175
  //debugOut.analog[10] = dThrottleP;
176
  //debugOut.analog[11] = dThrottleI;
177
  //debugOut.analog[12] = dThrottleD;
2095 - 178
  //debugOut.analog[13] = heightError/10;
2032 - 179
 
2071 - 180
  int16_t dThrottle = dThrottleI + dThrottleP - dThrottleD;
2035 - 181
 
1961 - 182
  if (dThrottle > staticParams.heightControlMaxThrottleChange)
183
    dThrottle = staticParams.heightControlMaxThrottleChange;
184
  else if (dThrottle < -staticParams.heightControlMaxThrottleChange)
185
    dThrottle = -staticParams.heightControlMaxThrottleChange;
2026 - 186
 
2055 - 187
  /*
2035 - 188
  debugOut.analog[19] = throttle;
189
  debugOut.analog[20] = dThrottle;
190
  debugOut.analog[21] = height;
191
  debugOut.analog[22] = rampedTargetHeight;
192
  debugOut.analog[23] = heightError;
2055 - 193
  */
2026 - 194
 
1961 - 195
  if (staticParams.bitConfig & CFG_SIMPLE_HEIGHT_CONTROL) {
2069 - 196
    if (!(staticParams.bitConfig & CFG_SIMPLE_HC_HOLD_SWITCH) || HC_isSwitchOn()) {
1960 - 197
      // If switch is not in use --> Just apply height control.
198
      // If switch is in use     --> only apply height control when switch is also ON.
199
      throttle += dThrottle;
200
    }
201
  }
1961 - 202
 
203
  /* Experiment: Find hover-throttle */
204
 
2189 - 205
#define DEFAULT_HOVERTHROTTLE 200
1961 - 206
int32_t stronglyFilteredHeightDiff = 0;
2036 - 207
// uint16_t hoverThrottle = 0; // DEFAULT_HOVERTHROTTLE;
1961 - 208
uint16_t stronglyFilteredThrottle = DEFAULT_HOVERTHROTTLE;
209
#define HOVERTHROTTLEFILTER 25
1960 - 210
 
211
  stronglyFilteredHeightDiff = (stronglyFilteredHeightDiff
212
                                * (HOVERTHROTTLEFILTER - 1) + dHeight) / HOVERTHROTTLEFILTER;
213
  stronglyFilteredThrottle = (stronglyFilteredThrottle * (HOVERTHROTTLEFILTER
214
                                                          - 1) + throttle) / HOVERTHROTTLEFILTER;
215
 
2035 - 216
  /*
1960 - 217
  if (isFlying >= 1000 && stronglyFilteredHeightDiff < 3
218
      && stronglyFilteredHeightDiff > -3) {
219
    hoverThrottle = stronglyFilteredThrottle;
220
    debugOut.digital[0] |= DEBUG_HOVERTHROTTLE;
221
  } else
222
    debugOut.digital[0] &= ~DEBUG_HOVERTHROTTLE;
2035 - 223
 
224
    */
1960 - 225
 
2189 - 226
  RPTY[CONTROL_THROTTLE] = throttle;
1775 - 227
}
228
 
229
/*
1821 - 230
 For a variometer thingy:
231
 When switch is thrown on, freeze throttle (capture it into variable)
232
 For each iter., add (throttle - frozen throttle) to target height. Maybe don't do ramping.
233
 Output = frozen throttle + whatever is computed +/-. Integral?
234
 */