Subversion Repositories FlightCtrl

Rev

Rev 1922 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1910 - 1
#include <stdlib.h>
2
#include "controlMixer.h"
3
#include "rc.h"
4
#include "attitude.h"
5
#include "externalControl.h"
6
#include "configuration.h"
7
#include "attitude.h"
8
#include "commands.h"
9
#include "output.h"
10
 
11
uint16_t maxControl[2] = {0, 0};
12
uint16_t controlActivity = 0;
13
int16_t control[4] = {0, 0, 0, 0};
14
int32_t controlIntegrals[4] = {0, 0, 0, 0};
15
 
16
// Internal variables for reading commands made with an R/C stick.
17
uint8_t lastCommand = COMMAND_NONE;
18
uint8_t lastArgument;
19
 
20
uint8_t isCommandRepeated = 0;
21
 
22
// MK flags. TODO: Replace by enum. State machine.
23
uint16_t isFlying = 0;
24
volatile uint8_t MKFlags = 0;
25
 
26
/*
27
 * This could be expanded to take arguments from ohter sources than the RC
28
 * (read: Custom MK RC project)
29
 */
30
uint8_t controlMixer_getArgument(void) {
31
  return lastArgument;
32
}
33
 
34
/*
35
 * This could be expanded to take calibrate / start / stop commands from ohter sources
36
 * than the R/C (read: Custom MK R/C project)
37
 */
38
uint8_t controlMixer_getCommand(void) {
39
  return lastCommand;
40
}
41
 
42
uint8_t controlMixer_isCommandRepeated(void) {
43
  return isCommandRepeated;
44
}
45
 
46
void controlMixer_setNeutral() {
47
  //EC_setNeutral();
48
  //HC_setGround();
49
}
50
 
51
/*
52
 * Set the potientiometer values to the momentary values of the respective R/C channels.
53
 * No slew rate limitation.
54
 */
55
void controlMixer_initVariables(void) {
56
  uint8_t i;
57
  for (i = 0; i < 8; i++) {
58
    variables[i] = RC_getVariable(i);
59
  }
60
}
61
 
62
/*
63
 * Update potentiometer values with limited slew rate. Could be made faster if desired.
64
 * TODO: It assumes R/C as source. Not necessarily true.
65
 */
66
void controlMixer_updateVariables(void) {
67
  uint8_t i;
68
  int16_t targetvalue;
69
  for (i = 0; i < 8; i++) {
70
    targetvalue = RC_getVariable(i);
71
    if (targetvalue < 0)
72
      targetvalue = 0;
73
    if (variables[i] < targetvalue && variables[i] < 255)
74
      variables[i]++;
75
    else if (variables[i] > 0 && variables[i] > targetvalue)
76
      variables[i]--;
77
  }
78
}
79
 
80
uint8_t controlMixer_getSignalQuality(void) {
81
  uint8_t rcQ = RC_getSignalQuality();
82
  uint8_t ecQ = EC_getSignalQuality();
83
  // This needs not be the only correct solution...
84
  return rcQ > ecQ ? rcQ : ecQ;
85
}
86
 
87
void updateControlAndMeasureControlActivity(uint8_t index, int16_t newValue) {
88
  int16_t tmp = control[index];
89
 
90
  // TODO: Scale by some factor. To be determined.
91
  controlIntegrals[index] += tmp * 4;
92
 
93
  if (controlIntegrals[index] > PITCHROLLOVER180) {
94
    controlIntegrals[index] -= PITCHROLLOVER360;
95
  } else if (controlIntegrals[index] <= -PITCHROLLOVER180) {
96
    controlIntegrals[index] += PITCHROLLOVER360;
97
  }
98
 
99
  control[index] = newValue;
100
  tmp -= newValue;
101
  tmp = tmp * tmp;
102
  // tmp += (newValue >= 0) ? newValue : -newValue;
103
  controlActivity += tmp;
104
}
105
 
106
#define CADAMPING 10
107
void dampenControlActivity(void) {
108
  int32_t tmp = controlActivity;
109
  tmp *= ((1<<CADAMPING)-1);
110
  tmp >>= CADAMPING;
111
  controlActivity = tmp;
112
}
113
 
114
/*
115
 * Update the variables indicating stick position from the sum of R/C, GPS and external control.
116
 */
117
void controlMixer_update(void) {
118
  // calculate Stick inputs by rc channels (P) and changing of rc channels (D)
119
  // TODO: If no signal --> zero.
120
  uint8_t axis;
121
 
122
  RC_update();
123
  // EC_update();
124
  // HC_update();
125
 
126
  int16_t* RC_EATR = RC_getEATR();
127
  // int16_t* EC_PRTY = EC_getPRTY();
128
 
129
  updateControlAndMeasureControlActivity(CONTROL_ELEVATOR, RC_EATR[CONTROL_ELEVATOR] /* + EC_PRTY[CONTROL_PITCH] */);
130
  updateControlAndMeasureControlActivity(CONTROL_AILERONS, RC_EATR[CONTROL_AILERONS] /* + EC_PRTY[CONTROL_ROLL] */);
131
  updateControlAndMeasureControlActivity(CONTROL_RUDDER, RC_EATR[CONTROL_RUDDER] /* + EC_PRTY[CONTROL_YAW] */);
132
  dampenControlActivity();
133
 
134
  // Do we also want to have activity measurement on throttle?
135
  control[CONTROL_THROTTLE] = RC_EATR[CONTROL_THROTTLE]; // + EC_PRTY[CONTROL_THROTTLE]);
136
 
137
  if (controlMixer_getSignalQuality() >= SIGNAL_GOOD) {
138
    controlMixer_updateVariables();
139
    configuration_staticToDynamic();
140
  } else { // Signal is not OK
141
    // Could handle switch to emergency flight here.
142
    // throttle is handled elsewhere.
143
  }
144
 
145
  // part1a end.
146
 
147
  /* This is not really necessary with the dead-band feature on all sticks (see rc.c)
148
     if(staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE)) {
149
     if (controlYaw > 2) controlYaw-= 2;
150
     else if (controlYaw< -2) controlYaw += 2;
151
     else controlYaw = 0;
152
     }
153
  */
154
 
155
  /*
156
   * Record maxima
157
   */
158
  for (axis = PITCH; axis <= ROLL; axis++) {
159
    if (abs(control[axis]) > maxControl[axis]) {
160
      maxControl[axis] = abs(control[axis]);
161
      if (maxControl[axis] > 100)
162
        maxControl[axis] = 100;
163
    } else if (maxControl[axis])
164
      maxControl[axis]--;
165
  }
166
 
167
  uint8_t rcCommand = (RC_getSignalQuality() >= SIGNAL_OK) ? RC_getCommand() : COMMAND_NONE;
168
  //  uint8_t ecCommand = (EC_getSignalQuality() >= SIGNAL_OK) ? EC_getCommand() : COMMAND_NONE;
169
 
170
  if (rcCommand != COMMAND_NONE) {
171
    isCommandRepeated = (lastCommand == rcCommand);
172
    lastCommand = rcCommand;
173
    lastArgument = RC_getArgument();
174
  } /*else if (ecCommand != COMMAND_NONE) {
175
      isCommandRepeated = (lastCommand == ecCommand);
176
                lastCommand = ecCommand;
177
                lastArgument = EC_getArgument();
178
                } */
179
  else {
180
    // Both sources have no command, or one or both are out.
181
    // Just set to false. There is no reason to check if the none-command was repeated anyway.
182
    isCommandRepeated = 0;
183
    lastCommand = COMMAND_NONE;
184
  }
185
}
186
 
187
// TODO: Integrate into command system.
188
uint8_t controlMixer_testCompassCalState(void) {
189
        return RC_testCompassCalState();
190
}