Subversion Repositories FlightCtrl

Rev

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

Rev Author Line No. Line
1775 - 1
#include <inttypes.h>
2033 - 2
#include "analog.h"
1775 - 3
#include "attitude.h"
4
#include "uart0.h"
5
#include "configuration.h"
2048 - 6
#include "controlMixer.h"
1775 - 7
 
8
// for digital / LED debug.
9
#include "output.h"
10
 
11
// For scope debugging only!
12
#include "rc.h"
13
 
14
#define INTEGRAL_LIMIT 100000
15
 
16
#define LATCH_TIME 40
17
 
18
int32_t targetHeight;
19
int32_t rampedTargetHeight;
20
 
21
uint8_t heightRampingTimer = 0;
1961 - 22
int32_t maxHeightThisFlight;
1775 - 23
int32_t iHeight;
24
 
25
void HC_setGround(void) {
2033 - 26
  analog_setGround();
1960 - 27
  // This should also happen when height control is enabled in-flight.
2033 - 28
  rampedTargetHeight = targetHeight = analog_getHeight();
1961 - 29
  maxHeightThisFlight = 0;
1960 - 30
  iHeight = 0;
1775 - 31
}
32
 
2039 - 33
void HC_periodicTask(void) {
2033 - 34
  int32_t height = analog_getHeight();
1960 - 35
  static uint8_t setHeightLatch = 0;
36
 
1961 - 37
  if (height > maxHeightThisFlight)
38
    maxHeightThisFlight = height;
1960 - 39
 
1961 - 40
  if (staticParams.bitConfig & CFG_SIMPLE_HC_HOLD_SWITCH) {
1960 - 41
    // If switch is activated in config, the MaxHeight parameter is a switch value: ON in both ends of the range; OFF in the middle.
42
    if (dynamicParams.heightSetting < 40 || dynamicParams.heightSetting > 255 - 40) {
43
      // Switch is ON
44
      if (setHeightLatch <= LATCH_TIME) {
45
        if (setHeightLatch == LATCH_TIME) {
46
          // Freeze the height as target. We want to do this exactly once each time the switch is thrown ON.
2033 - 47
          rampedTargetHeight = targetHeight = height;
1775 - 48
        }
1960 - 49
        // Time not yet reached.
50
        setHeightLatch++;
51
      }
52
    } else {
53
      // Switch is OFF.
54
      setHeightLatch = 0;
55
    }
56
  } else {
57
    // Switch is not activated; take the "max-height" as the target height.
2033 - 58
    targetHeight = (uint16_t) dynamicParams.heightSetting * 25L - 500L; // should be: 100 (or make a param out of it)
1960 - 59
  }
60
 
61
  if (++heightRampingTimer == INTEGRATION_FREQUENCY / 10) {
62
    heightRampingTimer = 0;
1961 - 63
    if (rampedTargetHeight < targetHeight) {
64
      // climbing
65
      if (rampedTargetHeight < targetHeight - staticParams.heightSlewRate) {
66
        rampedTargetHeight += staticParams.heightSlewRate;
67
      } else {
68
        rampedTargetHeight = targetHeight;
69
      }
2026 - 70
    } else {
1961 - 71
      // descending
72
      if (rampedTargetHeight > targetHeight + staticParams.heightSlewRate) {
73
        rampedTargetHeight -= staticParams.heightSlewRate;
74
      } else {
75
        rampedTargetHeight = targetHeight;
76
      }
1960 - 77
    }
78
  }
1970 - 79
 
1960 - 80
  // height, in meters (so the division factor is: 100)
2045 - 81
  // debugOut.analog[31] = (117100 - filteredAirPressure) / 100;
1971 - 82
  // Calculated 0 alt number: 108205
1980 - 83
  // Experimental 0 alt number: 117100
1775 - 84
}
85
 
86
// takes 180-200 usec (with integral term). That is too heavy!!!
87
// takes 100 usec without integral term.
2048 - 88
void HC_periodicTaskAndPRTY(int16_t* PRTY) {
89
  HC_periodicTask();
90
  int16_t throttle = PRTY[CONTROL_THROTTLE];
2033 - 91
  int32_t height = analog_getHeight();
1960 - 92
  int32_t heightError = rampedTargetHeight - height;
2033 - 93
  int16_t dHeight = analog_getDHeight();
94
  //lastHeight = height;
1960 - 95
 
2026 - 96
  if (heightError > 0) {
1960 - 97
    debugOut.digital[0] |= DEBUG_HEIGHT_DIFF;
2035 - 98
  } else {
1961 - 99
    debugOut.digital[0] &= ~DEBUG_HEIGHT_DIFF;
2035 - 100
  }
101
 
102
  if (dHeight > 0) {
1960 - 103
    debugOut.digital[1] |= DEBUG_HEIGHT_DIFF;
2035 - 104
  } else {
105
    debugOut.digital[1] &= ~DEBUG_HEIGHT_DIFF;
1960 - 106
  }
2032 - 107
 
2033 - 108
  // iHeight, at a difference of 5 meters and a freq. of 488 Hz, will grow with 244000 / sec....
109
  iHeight += heightError;
2032 - 110
 
2033 - 111
#define IHEIGHT_SCALE 24
112
  // dThrottle is in the range between +/- 1<<(IHEIGHT_SCALE+8)>>(IHEIGHT_SCALE) = +/- 256
2035 - 113
  int16_t dThrottleI =  (iHeight * (int32_t)dynamicParams.heightI) >> (IHEIGHT_SCALE);
2033 - 114
 
2035 - 115
  if (dThrottleI > staticParams.heightControlMaxIntegral) {
116
    dThrottleI = staticParams.heightControlMaxIntegral;
117
    iHeight = ((int32_t)staticParams.heightControlMaxIntegral << IHEIGHT_SCALE) / dynamicParams.heightI;
118
  } else if (dThrottleI < -staticParams.heightControlMaxIntegral) {
119
    dThrottleI = -staticParams.heightControlMaxIntegral;
120
    iHeight = -((int32_t)staticParams.heightControlMaxIntegral << IHEIGHT_SCALE) / dynamicParams.heightI;
2033 - 121
  }
122
 
2035 - 123
  int16_t dThrottleP = (heightError * dynamicParams.heightP) >> 10;
124
  int16_t dThrottleD = (dHeight * dynamicParams.heightD) >> 7;
2033 - 125
 
2035 - 126
  debugOut.analog[24] = dThrottleP;
127
  debugOut.analog[25] = dThrottleI;
128
  debugOut.analog[26] = dThrottleD;
2032 - 129
 
2045 - 130
  //debugOut.analog[27] = dynamicParams.heightP;
131
  //debugOut.analog[28] = dynamicParams.heightI;
132
  //debugOut.analog[29] = dynamicParams.heightD;
2035 - 133
 
134
  int16_t dThrottle = dThrottleI + dThrottleP + dThrottleD;
135
 
1961 - 136
  if (dThrottle > staticParams.heightControlMaxThrottleChange)
137
    dThrottle = staticParams.heightControlMaxThrottleChange;
138
  else if (dThrottle < -staticParams.heightControlMaxThrottleChange)
139
    dThrottle = -staticParams.heightControlMaxThrottleChange;
2026 - 140
 
2035 - 141
  debugOut.analog[19] = throttle;
142
  debugOut.analog[20] = dThrottle;
143
  debugOut.analog[21] = height;
144
  debugOut.analog[22] = rampedTargetHeight;
145
  debugOut.analog[23] = heightError;
2026 - 146
 
1961 - 147
  if (staticParams.bitConfig & CFG_SIMPLE_HEIGHT_CONTROL) {
148
    if (!(staticParams.bitConfig & CFG_SIMPLE_HC_HOLD_SWITCH)
1960 - 149
        || (dynamicParams.heightSetting < 40 || dynamicParams.heightSetting > 255 - 40)) {
150
      // If switch is not in use --> Just apply height control.
151
      // If switch is in use     --> only apply height control when switch is also ON.
152
      throttle += dThrottle;
153
    }
154
  }
1961 - 155
 
156
  /* Experiment: Find hover-throttle */
157
 
158
#define DEFAULT_HOVERTHROTTLE 50
159
int32_t stronglyFilteredHeightDiff = 0;
2036 - 160
// uint16_t hoverThrottle = 0; // DEFAULT_HOVERTHROTTLE;
1961 - 161
uint16_t stronglyFilteredThrottle = DEFAULT_HOVERTHROTTLE;
162
#define HOVERTHROTTLEFILTER 25
1960 - 163
 
164
  stronglyFilteredHeightDiff = (stronglyFilteredHeightDiff
165
                                * (HOVERTHROTTLEFILTER - 1) + dHeight) / HOVERTHROTTLEFILTER;
166
  stronglyFilteredThrottle = (stronglyFilteredThrottle * (HOVERTHROTTLEFILTER
167
                                                          - 1) + throttle) / HOVERTHROTTLEFILTER;
168
 
2035 - 169
  /*
1960 - 170
  if (isFlying >= 1000 && stronglyFilteredHeightDiff < 3
171
      && stronglyFilteredHeightDiff > -3) {
172
    hoverThrottle = stronglyFilteredThrottle;
173
    debugOut.digital[0] |= DEBUG_HOVERTHROTTLE;
174
  } else
175
    debugOut.digital[0] &= ~DEBUG_HOVERTHROTTLE;
2035 - 176
 
177
    */
1960 - 178
 
2048 - 179
  PRTY[CONTROL_THROTTLE] = throttle;
1775 - 180
}
181
 
182
/*
1821 - 183
 For a variometer thingy:
184
 When switch is thrown on, freeze throttle (capture it into variable)
185
 For each iter., add (throttle - frozen throttle) to target height. Maybe don't do ramping.
186
 Output = frozen throttle + whatever is computed +/-. Integral?
187
 */