Subversion Repositories FlightCtrl

Rev

Rev 2033 | Rev 2036 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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