Rev 2049 | Rev 2052 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1612 | dongfang | 1 | #include <stdlib.h> |
2 | #include "controlMixer.h" |
||
3 | #include "rc.h" |
||
1775 | - | 4 | #include "heightControl.h" |
5 | #include "attitudeControl.h" |
||
1612 | dongfang | 6 | #include "externalControl.h" |
2048 | - | 7 | #include "compassControl.h" |
2039 | - | 8 | #include "naviControl.h" |
1612 | dongfang | 9 | #include "configuration.h" |
10 | #include "attitude.h" |
||
1775 | - | 11 | #include "commands.h" |
12 | #include "output.h" |
||
1612 | dongfang | 13 | |
1908 | - | 14 | // uint16_t maxControl[2] = { 0, 0 }; |
15 | uint16_t controlActivity = 0; |
||
16 | int16_t controls[4] = { 0, 0, 0, 0 }; |
||
1612 | dongfang | 17 | |
18 | // Internal variables for reading commands made with an R/C stick. |
||
1821 | - | 19 | uint8_t lastCommand = COMMAND_NONE; |
1775 | - | 20 | uint8_t lastArgument; |
1612 | dongfang | 21 | |
1775 | - | 22 | uint8_t isCommandRepeated = 0; |
1963 | - | 23 | uint8_t controlMixer_didReceiveSignal = 0; |
1775 | - | 24 | |
1612 | dongfang | 25 | /* |
26 | * This could be expanded to take arguments from ohter sources than the RC |
||
27 | * (read: Custom MK RC project) |
||
28 | */ |
||
29 | uint8_t controlMixer_getArgument(void) { |
||
1961 | - | 30 | return lastArgument; |
1612 | dongfang | 31 | } |
32 | |||
33 | /* |
||
34 | * This could be expanded to take calibrate / start / stop commands from ohter sources |
||
35 | * than the R/C (read: Custom MK R/C project) |
||
36 | */ |
||
37 | uint8_t controlMixer_getCommand(void) { |
||
1961 | - | 38 | return lastCommand; |
1612 | dongfang | 39 | } |
40 | |||
41 | uint8_t controlMixer_isCommandRepeated(void) { |
||
1961 | - | 42 | return isCommandRepeated; |
1612 | dongfang | 43 | } |
44 | |||
1775 | - | 45 | void controlMixer_setNeutral() { |
1961 | - | 46 | for (uint8_t i=0; i<VARIABLE_COUNT; i++) { |
47 | variables[i] = 0; |
||
48 | } |
||
49 | EC_setNeutral(); |
||
50 | HC_setGround(); |
||
1612 | dongfang | 51 | } |
52 | |||
53 | /* |
||
54 | * Set the potientiometer values to the momentary values of the respective R/C channels. |
||
55 | * No slew rate limitation. |
||
56 | */ |
||
57 | void controlMixer_initVariables(void) { |
||
1961 | - | 58 | uint8_t i; |
59 | for (i=0; i < VARIABLE_COUNT; i++) { |
||
60 | variables[i] = RC_getVariable(i); |
||
61 | } |
||
1612 | dongfang | 62 | } |
63 | |||
64 | /* |
||
65 | * Update potentiometer values with limited slew rate. Could be made faster if desired. |
||
1775 | - | 66 | * TODO: It assumes R/C as source. Not necessarily true. |
1612 | dongfang | 67 | */ |
68 | void controlMixer_updateVariables(void) { |
||
1961 | - | 69 | uint8_t i; |
70 | int16_t targetvalue; |
||
71 | for (i=0; i < VARIABLE_COUNT; i++) { |
||
72 | targetvalue = RC_getVariable(i); |
||
73 | if (targetvalue < 0) |
||
74 | targetvalue = 0; |
||
75 | if (variables[i] < targetvalue && variables[i] < 255) |
||
76 | variables[i]++; |
||
77 | else if (variables[i] > 0 && variables[i] > targetvalue) |
||
78 | variables[i]--; |
||
79 | } |
||
1612 | dongfang | 80 | } |
81 | |||
82 | uint8_t controlMixer_getSignalQuality(void) { |
||
1961 | - | 83 | uint8_t rcQ = RC_getSignalQuality(); |
84 | uint8_t ecQ = EC_getSignalQuality(); |
||
1964 | - | 85 | |
1961 | - | 86 | // This needs not be the only correct solution... |
87 | return rcQ > ecQ ? rcQ : ecQ; |
||
1612 | dongfang | 88 | } |
89 | |||
1908 | - | 90 | void updateControlAndMeasureControlActivity(uint8_t index, int16_t newValue) { |
1961 | - | 91 | int16_t tmp = controls[index]; |
92 | controls[index] = newValue; |
||
2017 | - | 93 | |
1961 | - | 94 | tmp -= newValue; |
95 | tmp /= 2; |
||
96 | tmp = tmp * tmp; |
||
97 | // tmp += (newValue >= 0) ? newValue : -newValue; |
||
1986 | - | 98 | /* |
1961 | - | 99 | if (controlActivity + (uint16_t)tmp >= controlActivity) |
100 | controlActivity += tmp; |
||
101 | else controlActivity = 0xffff; |
||
1986 | - | 102 | */ |
103 | if (controlActivity + (uint16_t)tmp < 32768) |
||
104 | controlActivity += tmp; |
||
1908 | - | 105 | } |
106 | |||
107 | #define CADAMPING 10 |
||
108 | void dampenControlActivity(void) { |
||
1961 | - | 109 | uint32_t tmp = controlActivity; |
110 | tmp *= ((1<<CADAMPING)-1); |
||
111 | tmp >>= CADAMPING; |
||
112 | controlActivity = tmp; |
||
1908 | - | 113 | } |
114 | |||
1612 | dongfang | 115 | /* |
2048 | - | 116 | * Update the variables indicating stick position from the sum of R/C, GPS and external control |
117 | * and whatever other controls we invented in the meantime... |
||
118 | * Update variables. |
||
119 | * Decode commands but do not execute them. |
||
1612 | dongfang | 120 | */ |
2048 | - | 121 | int16_t tempPRTY[4]; |
122 | |||
2039 | - | 123 | void controlMixer_periodicTask(void) { |
2049 | - | 124 | // Decode commands. |
125 | uint8_t rcCommand = (RC_getSignalQuality() >= SIGNAL_OK) ? RC_getCommand() |
||
126 | : COMMAND_NONE; |
||
127 | uint8_t ecCommand = (EC_getSignalQuality() >= SIGNAL_OK) ? EC_getCommand() |
||
128 | : COMMAND_NONE; |
||
129 | |||
130 | // Update variables ("potis"). |
||
131 | if (controlMixer_getSignalQuality() >= SIGNAL_GOOD) { |
||
132 | controlMixer_updateVariables(); |
||
133 | controlMixer_didReceiveSignal = 1; |
||
134 | } else { // Signal is not OK |
||
135 | // Could handle switch to emergency flight here. |
||
136 | // throttle is handled elsewhere. |
||
137 | } |
||
138 | |||
139 | if (rcCommand != COMMAND_NONE) { |
||
140 | isCommandRepeated = (lastCommand == rcCommand); |
||
141 | lastCommand = rcCommand; |
||
142 | lastArgument = RC_getArgument(); |
||
143 | } else if (ecCommand != COMMAND_NONE) { |
||
144 | isCommandRepeated = (lastCommand == ecCommand); |
||
145 | lastCommand = ecCommand; |
||
146 | lastArgument = EC_getArgument(); |
||
147 | } else { |
||
148 | // Both sources have no command, or one or both are out. |
||
149 | // Just set to false. There is no reason to check if the none-command was repeated anyway. |
||
150 | isCommandRepeated = 0; |
||
151 | lastCommand = COMMAND_NONE; |
||
152 | } |
||
1961 | - | 153 | |
2048 | - | 154 | // This will init the values (not just add to them). |
155 | RC_periodicTaskAndPRTY(tempPRTY); |
||
2045 | - | 156 | |
2048 | - | 157 | // Add external control to RC |
158 | EC_periodicTaskAndPRTY(tempPRTY); |
||
2039 | - | 159 | |
2048 | - | 160 | // Add navigations control to RC and external control. |
161 | navigation_periodicTaskAndPRTY(tempPRTY); |
||
2039 | - | 162 | |
2048 | - | 163 | // Add compass control (could also have been before navi, they are independent) |
164 | CC_periodicTaskAndPRTY(tempPRTY); |
||
165 | |||
166 | // Add height control (could also have been before navi and/or compass, they are independent) |
||
167 | HC_periodicTaskAndPRTY(tempPRTY); |
||
168 | |||
169 | // Add attitude control (could also have been before navi and/or compass, they are independent) |
||
170 | AC_getPRTY(tempPRTY); |
||
171 | |||
172 | // Commit results to global variable and also measure control activity. |
||
2051 | - | 173 | controls[CONTROL_THROTTLE] = tempPRTY[CONTROL_THROTTLE]; |
2048 | - | 174 | updateControlAndMeasureControlActivity(CONTROL_PITCH, tempPRTY[CONTROL_PITCH]); |
175 | updateControlAndMeasureControlActivity(CONTROL_ROLL, tempPRTY[CONTROL_ROLL]); |
||
176 | updateControlAndMeasureControlActivity(CONTROL_YAW, tempPRTY[CONTROL_YAW]); |
||
1961 | - | 177 | dampenControlActivity(); |
1775 | - | 178 | |
1986 | - | 179 | debugOut.analog[17] = controlActivity/10; |
1961 | - | 180 | |
1980 | - | 181 | // We can safely do this even with a bad signal - the variables will not have been updated then. |
182 | configuration_applyVariablesToParams(); |
||
1961 | - | 183 | |
184 | // part1a end. |
||
185 | |||
186 | /* This is not really necessary with the dead-band feature on all sticks (see rc.c) |
||
187 | if(staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE)) { |
||
188 | if (controlYaw > 2) controlYaw-= 2; |
||
189 | else if (controlYaw< -2) controlYaw += 2; |
||
190 | else controlYaw = 0; |
||
191 | } |
||
192 | */ |
||
193 | |||
194 | /* |
||
2048 | - | 195 | * Record maxima. Predecessor of the control activity stuff. |
1961 | - | 196 | for (axis = PITCH; axis <= ROLL; axis++) { |
197 | if (abs(control[axis] / CONTROL_SCALING) > maxControl[axis]) { |
||
198 | maxControl[axis] = abs(control[axis]) / CONTROL_SCALING; |
||
199 | if (maxControl[axis] > 100) |
||
200 | maxControl[axis] = 100; |
||
201 | } else if (maxControl[axis]) |
||
202 | maxControl[axis]--; |
||
203 | } |
||
204 | */ |
||
1964 | - | 205 | } |