Subversion Repositories FlightCtrl

Rev

Rev 1922 | Rev 2102 | 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 "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};
1922 - 14
// int32_t controlIntegrals[4] = {0, 0, 0, 0};
1910 - 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.
1922 - 91
  // controlIntegrals[index] += tmp * 4;
1910 - 92
 
1922 - 93
  /*
1910 - 94
  if (controlIntegrals[index] > PITCHROLLOVER180) {
95
    controlIntegrals[index] -= PITCHROLLOVER360;
96
  } else if (controlIntegrals[index] <= -PITCHROLLOVER180) {
97
    controlIntegrals[index] += PITCHROLLOVER360;
98
  }
1926 - 99
  */
1910 - 100
 
101
  control[index] = newValue;
102
  tmp -= newValue;
103
  tmp = tmp * tmp;
104
  // tmp += (newValue >= 0) ? newValue : -newValue;
105
  controlActivity += tmp;
106
}
107
 
108
#define CADAMPING 10
109
void dampenControlActivity(void) {
110
  int32_t tmp = controlActivity;
111
  tmp *= ((1<<CADAMPING)-1);
112
  tmp >>= CADAMPING;
113
  controlActivity = tmp;
114
}
115
 
116
/*
117
 * Update the variables indicating stick position from the sum of R/C, GPS and external control.
118
 */
119
void controlMixer_update(void) {
120
  // calculate Stick inputs by rc channels (P) and changing of rc channels (D)
121
  // TODO: If no signal --> zero.
122
  uint8_t axis;
123
 
124
  RC_update();
125
  // EC_update();
126
  // HC_update();
127
 
128
  int16_t* RC_EATR = RC_getEATR();
129
  // int16_t* EC_PRTY = EC_getPRTY();
130
 
131
  updateControlAndMeasureControlActivity(CONTROL_ELEVATOR, RC_EATR[CONTROL_ELEVATOR] /* + EC_PRTY[CONTROL_PITCH] */);
132
  updateControlAndMeasureControlActivity(CONTROL_AILERONS, RC_EATR[CONTROL_AILERONS] /* + EC_PRTY[CONTROL_ROLL] */);
133
  updateControlAndMeasureControlActivity(CONTROL_RUDDER, RC_EATR[CONTROL_RUDDER] /* + EC_PRTY[CONTROL_YAW] */);
134
  dampenControlActivity();
135
 
136
  // Do we also want to have activity measurement on throttle?
137
  control[CONTROL_THROTTLE] = RC_EATR[CONTROL_THROTTLE]; // + EC_PRTY[CONTROL_THROTTLE]);
138
 
139
  if (controlMixer_getSignalQuality() >= SIGNAL_GOOD) {
140
    controlMixer_updateVariables();
141
    configuration_staticToDynamic();
142
  } else { // Signal is not OK
143
    // Could handle switch to emergency flight here.
144
    // throttle is handled elsewhere.
145
  }
146
 
147
  // part1a end.
148
 
149
  /* This is not really necessary with the dead-band feature on all sticks (see rc.c)
150
     if(staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE)) {
151
     if (controlYaw > 2) controlYaw-= 2;
152
     else if (controlYaw< -2) controlYaw += 2;
153
     else controlYaw = 0;
154
     }
155
  */
156
 
157
  /*
158
   * Record maxima
159
   */
160
  for (axis = PITCH; axis <= ROLL; axis++) {
161
    if (abs(control[axis]) > maxControl[axis]) {
162
      maxControl[axis] = abs(control[axis]);
163
      if (maxControl[axis] > 100)
164
        maxControl[axis] = 100;
165
    } else if (maxControl[axis])
166
      maxControl[axis]--;
167
  }
168
 
169
  uint8_t rcCommand = (RC_getSignalQuality() >= SIGNAL_OK) ? RC_getCommand() : COMMAND_NONE;
170
  //  uint8_t ecCommand = (EC_getSignalQuality() >= SIGNAL_OK) ? EC_getCommand() : COMMAND_NONE;
171
 
172
  if (rcCommand != COMMAND_NONE) {
173
    isCommandRepeated = (lastCommand == rcCommand);
174
    lastCommand = rcCommand;
175
    lastArgument = RC_getArgument();
176
  } /*else if (ecCommand != COMMAND_NONE) {
177
      isCommandRepeated = (lastCommand == ecCommand);
178
                lastCommand = ecCommand;
179
                lastArgument = EC_getArgument();
180
                } */
181
  else {
182
    // Both sources have no command, or one or both are out.
183
    // Just set to false. There is no reason to check if the none-command was repeated anyway.
184
    isCommandRepeated = 0;
185
    lastCommand = COMMAND_NONE;
186
  }
187
}
188
 
189
// TODO: Integrate into command system.
190
uint8_t controlMixer_testCompassCalState(void) {
191
        return RC_testCompassCalState();
192
}