Rev 2089 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2089 | Rev 2189 | ||
---|---|---|---|
1 | #include <stdlib.h> |
1 | #include <stdlib.h> |
2 | #include "controlMixer.h" |
2 | #include "controlMixer.h" |
3 | #include "rc.h" |
3 | #include "rc.h" |
4 | #include "heightControl.h" |
4 | #include "heightControl.h" |
5 | #include "attitudeControl.h" |
- | |
6 | #include "externalControl.h" |
5 | #include "externalControl.h" |
7 | #include "compassControl.h" |
6 | #include "compassControl.h" |
8 | #include "failsafeControl.h" |
7 | #include "failsafeControl.h" |
9 | #include "naviControl.h" |
8 | #include "naviControl.h" |
10 | #include "configuration.h" |
9 | #include "configuration.h" |
11 | #include "attitude.h" |
10 | //#include "attitude.h" |
12 | #include "commands.h" |
11 | #include "commands.h" |
13 | #include "output.h" |
12 | #include "debug.h" |
- | 13 | #include "definitions.h" |
|
14 | 14 | ||
15 | // uint16_t maxControl[2] = { 0, 0 }; |
15 | // uint16_t maxControl[2] = { 0, 0 }; |
16 | // uint16_t controlActivity = 0; |
16 | // uint16_t controlActivity = 0; |
17 | int16_t controls[4] = { 0, 0, 0, 0 }; |
17 | int16_t controls[4]; |
18 | 18 | ||
19 | // Internal variables for reading commands made with an R/C stick. |
19 | // Internal variables for reading commands made with an R/C stick. |
20 | uint8_t lastCommand = COMMAND_NONE; |
20 | uint8_t lastCommand; |
21 | uint8_t lastArgument; |
21 | uint8_t lastArgument; |
22 | 22 | ||
23 | uint8_t isCommandRepeated = 0; |
23 | uint8_t isCommandRepeated; |
24 | uint8_t controlMixer_didReceiveSignal = 0; |
24 | uint8_t controlMixer_didReceiveSignal; |
25 | 25 | ||
26 | /* |
26 | /* |
27 | * This could be expanded to take arguments from ohter sources than the RC |
27 | * This could be expanded to take arguments from ohter sources than the RC |
28 | * (read: Custom MK RC project) |
28 | * (read: Custom MK RC project) |
29 | */ |
29 | */ |
30 | uint8_t controlMixer_getArgument(void) { |
30 | uint8_t controlMixer_getArgument(void) { |
31 | return lastArgument; |
31 | return lastArgument; |
32 | } |
32 | } |
33 | 33 | ||
34 | /* |
34 | /* |
35 | * This could be expanded to take calibrate / start / stop commands from ohter sources |
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) |
36 | * than the R/C (read: Custom MK R/C project) |
37 | */ |
37 | */ |
38 | uint8_t controlMixer_getCommand(void) { |
38 | uint8_t controlMixer_getCommand(void) { |
39 | return lastCommand; |
39 | return lastCommand; |
40 | } |
40 | } |
41 | 41 | ||
42 | uint8_t controlMixer_isCommandRepeated(void) { |
42 | uint8_t controlMixer_isCommandRepeated(void) { |
43 | return isCommandRepeated; |
43 | return isCommandRepeated; |
44 | } |
44 | } |
45 | - | ||
46 | void controlMixer_setNeutral() { |
- | |
47 | for (uint8_t i=0; i<VARIABLE_COUNT; i++) { |
- | |
48 | variables[i] = RC_getVariable(i); |
- | |
49 | } |
- | |
50 | EC_setNeutral(); |
- | |
51 | HC_setGround(); |
- | |
52 | FC_setNeutral(); // FC is FailsafeControl, not FlightCtrl. |
- | |
53 | - | ||
54 | // This is to set the home pos in navi. |
- | |
55 | // MKFlags |= MKFLAG_CALIBRATE; |
- | |
56 | } |
- | |
57 | 45 | ||
58 | /* |
- | |
59 | * Update potentiometer values with limited slew rate. Could be made faster if desired. |
46 | /* |
60 | * TODO: It assumes R/C as source. Not necessarily true. |
47 | * TODO: This assumes R/C as source. Not necessarily true. |
61 | */ |
48 | */ |
62 | void controlMixer_updateVariables(void) { |
49 | void controlMixer_updateVariables(void) { |
63 | uint8_t i; |
50 | uint8_t i; |
64 | int16_t targetvalue; |
- | |
65 | for (i=0; i < VARIABLE_COUNT; i++) { |
51 | for (i=0; i < VARIABLE_COUNT; i++) { |
66 | targetvalue = RC_getVariable(i); |
52 | int16_t targetvalue = RC_getVariable(i); |
67 | if (targetvalue < 0) |
53 | if (targetvalue < 0) |
68 | targetvalue = 0; |
54 | variables[i] = 0; |
69 | if (variables[i] < targetvalue && variables[i] < 255) |
55 | else if (targetvalue > 255) |
70 | variables[i]++; |
56 | variables[i] = 255; |
71 | else if (variables[i] > 0 && variables[i] > targetvalue) |
57 | else variables[i] = targetvalue; |
72 | variables[i]--; |
- | |
73 | } |
58 | } |
74 | } |
59 | } |
- | 60 | ||
- | 61 | void controlMixer_setNeutral() { |
|
- | 62 | controlMixer_updateVariables(); |
|
- | 63 | EC_setNeutral(); |
|
- | 64 | HC_setGround(); |
|
- | 65 | FC_setNeutral(); // FC is FailsafeControl, not FlightCtrl. |
|
- | 66 | ||
- | 67 | // This is to set the home pos in navi. |
|
- | 68 | // MKFlags |= MKFLAG_CALIBRATE; |
|
- | 69 | } |
|
75 | 70 | ||
76 | uint8_t controlMixer_getSignalQuality(void) { |
71 | uint8_t controlMixer_getSignalQuality(void) { |
77 | uint8_t rcQ = RC_getSignalQuality(); |
72 | uint8_t rcQ = RC_getSignalQuality(); |
78 | uint8_t ecQ = EC_getSignalQuality(); |
73 | uint8_t ecQ = EC_getSignalQuality(); |
79 | 74 | ||
80 | // This needs not be the only correct solution... |
75 | // This needs not be the only correct solution... |
81 | return rcQ > ecQ ? rcQ : ecQ; |
76 | return rcQ > ecQ ? rcQ : ecQ; |
82 | } |
77 | } |
83 | 78 | ||
84 | /* |
79 | /* |
85 | void updateControlAndMeasureControlActivity(uint8_t index, int16_t newValue) { |
80 | void updateControlAndMeasureControlActivity(uint8_t index, int16_t newValue) { |
86 | int16_t tmp = controls[index]; |
81 | int16_t tmp = controls[index]; |
87 | controls[index] = newValue; |
82 | controls[index] = newValue; |
88 | |
83 | |
89 | tmp -= newValue; |
84 | tmp -= newValue; |
90 | tmp /= 2; |
85 | tmp /= 2; |
91 | tmp = tmp * tmp; |
86 | tmp = tmp * tmp; |
92 | // tmp += (newValue >= 0) ? newValue : -newValue; |
87 | // tmp += (newValue >= 0) ? newValue : -newValue; |
93 | 88 | ||
94 | / * |
89 | / * |
95 | if (controlActivity + (uint16_t)tmp >= controlActivity) |
90 | if (controlActivity + (uint16_t)tmp >= controlActivity) |
96 | controlActivity += tmp; |
91 | controlActivity += tmp; |
97 | else controlActivity = 0xffff; |
92 | else controlActivity = 0xffff; |
98 | * / |
93 | * / |
99 | if (controlActivity + (uint16_t)tmp < 0x8000) |
94 | if (controlActivity + (uint16_t)tmp < 0x8000) |
100 | controlActivity += tmp; |
95 | controlActivity += tmp; |
101 | } |
96 | } |
102 | 97 | ||
103 | #define CADAMPING 10 |
98 | #define CADAMPING 10 |
104 | void dampenControlActivity(void) { |
99 | void dampenControlActivity(void) { |
105 | uint32_t tmp = controlActivity; |
100 | uint32_t tmp = controlActivity; |
106 | tmp *= ((1<<CADAMPING)-1); |
101 | tmp *= ((1<<CADAMPING)-1); |
107 | tmp >>= CADAMPING; |
102 | tmp >>= CADAMPING; |
108 | controlActivity = tmp; |
103 | controlActivity = tmp; |
109 | } |
104 | } |
110 | */ |
105 | */ |
111 | 106 | ||
112 | /* |
107 | /* |
113 | * Update the variables indicating stick position from the sum of R/C, GPS and external control |
108 | * Update the variables indicating stick position from the sum of R/C, GPS and external control |
114 | * and whatever other controls we invented in the meantime... |
109 | * and whatever other controls we invented in the meantime... |
115 | * Update variables. |
110 | * Update variables. |
116 | * Decode commands but do not execute them. |
111 | * Decode commands but do not execute them. |
117 | */ |
112 | */ |
118 | 113 | ||
119 | void controlMixer_periodicTask(void) { |
114 | void controlMixer_periodicTask(void) { |
120 | int16_t tempPRTY[4] = { 0, 0, 0, 0 }; |
115 | int16_t tempRPTY[4] = { 0, 0, 0, 0 }; |
121 | 116 | ||
122 | // Decode commands. |
117 | // Decode commands. |
123 | uint8_t rcCommand = (RC_getSignalQuality() >= SIGNAL_OK) ? RC_getCommand() |
118 | uint8_t rcCommand = (RC_getSignalQuality() >= SIGNAL_OK) ? RC_getCommand() |
124 | : COMMAND_NONE; |
119 | : COMMAND_NONE; |
125 | 120 | ||
126 | uint8_t ecCommand = (EC_getSignalQuality() >= SIGNAL_OK) ? EC_getCommand() |
121 | uint8_t ecCommand = (EC_getSignalQuality() >= SIGNAL_OK) ? EC_getCommand() |
127 | : COMMAND_NONE; |
122 | : COMMAND_NONE; |
128 | 123 | ||
129 | // Update variables ("potis"). |
124 | // Update variables ("potis"). |
130 | if (controlMixer_getSignalQuality() >= SIGNAL_GOOD) { |
125 | if (controlMixer_getSignalQuality() >= SIGNAL_GOOD) { |
131 | controlMixer_updateVariables(); |
126 | controlMixer_updateVariables(); |
132 | controlMixer_didReceiveSignal = 1; |
127 | controlMixer_didReceiveSignal = 1; |
133 | } else { // Signal is not OK |
128 | } else { // Signal is not OK |
134 | // Could handle switch to emergency flight here. |
129 | // Could handle switch to emergency flight here. |
135 | // throttle is handled elsewhere. |
130 | // throttle is handled elsewhere. |
136 | } |
131 | } |
137 | 132 | ||
138 | if (rcCommand != COMMAND_NONE) { |
133 | if (rcCommand != COMMAND_NONE) { |
139 | isCommandRepeated = (lastCommand == rcCommand); |
134 | isCommandRepeated = (lastCommand == rcCommand); |
140 | lastCommand = rcCommand; |
135 | lastCommand = rcCommand; |
141 | lastArgument = RC_getArgument(); |
136 | lastArgument = RC_getArgument(); |
142 | } else if (ecCommand != COMMAND_NONE) { |
137 | } else if (ecCommand != COMMAND_NONE) { |
143 | isCommandRepeated = (lastCommand == ecCommand); |
138 | isCommandRepeated = (lastCommand == ecCommand); |
144 | lastCommand = ecCommand; |
139 | lastCommand = ecCommand; |
145 | lastArgument = EC_getArgument(); |
140 | lastArgument = EC_getArgument(); |
- | 141 | if (ecCommand == COMMAND_GYROCAL) debugOut.digital[0] |= DEBUG_COMMAND; |
|
- | 142 | if (ecCommand == COMMAND_ACCCAL) debugOut.digital[1] |= DEBUG_COMMAND; |
|
146 | } else { |
143 | } else { |
147 | // Both sources have no command, or one or both are out. |
144 | // Both sources have no command, or one or both are out. |
148 | // Just set to false. There is no reason to check if the none-command was repeated anyway. |
145 | // Just set to false. There is no reason to check if the none-command was repeated anyway. |
149 | isCommandRepeated = 0; |
146 | isCommandRepeated = 0; |
150 | lastCommand = COMMAND_NONE; |
147 | lastCommand = COMMAND_NONE; |
151 | } |
148 | } |
152 | 149 | ||
153 | // This will init the values (not just add to them). |
150 | // This will init the values (not just add to them). |
154 | RC_periodicTaskAndPRTY(tempPRTY); |
151 | RC_periodicTaskAndRPTY(tempRPTY); |
155 | 152 | ||
156 | // Add external control to RC |
153 | // Add external control to RC |
157 | EC_periodicTaskAndPRTY(tempPRTY); |
154 | EC_periodicTaskAndRPTY(tempRPTY); |
158 | 155 | ||
159 | #ifdef USE_DIRECT_GPS |
156 | #ifdef USE_DIRECT_GPS |
160 | if (staticParams.bitConfig & (CFG_NAVI_ENABLED)) |
157 | if (staticParams.bitConfig & (CFG_NAVI_ENABLED)) |
161 | navigation_periodicTaskAndPRTY(tempPRTY); |
158 | navigation_periodicTaskAndRPTY(tempRPTY); |
162 | #endif |
159 | #endif |
163 | 160 | ||
164 | // Add compass control (could also have been before navi, they are independent) |
161 | // Add compass control (could also have been before navi, they are independent) |
165 | CC_periodicTaskAndPRTY(tempPRTY); |
162 | // CC_periodicTaskAndRPTY(tempRPTY); |
166 | - | ||
167 | FC_periodicTaskAndPRTY(tempPRTY); |
- | |
- | 163 | ||
- | 164 | FC_periodicTaskAndRPTY(tempRPTY); |
|
168 | 165 | ||
169 | // This is temporary. There might be some emergency height control also. |
166 | // This is temporary. There might be some emergency height control also. |
170 | if (!(MKFlags & MKFLAG_EMERGENCY_FLIGHT)) { |
167 | if (!(MKFlags & MKFLAG_EMERGENCY_FLIGHT)) { |
171 | // Add height control (could also have been before navi and/or compass, they are independent) |
168 | // Add height control (could also have been before navi and/or compass, they are independent) |
172 | HC_periodicTaskAndPRTY(tempPRTY); |
169 | HC_periodicTaskAndRPTY(tempRPTY); |
173 | 170 | ||
174 | // Add attitude control (could also have been before navi and/or compass, they are independent) |
171 | // Add attitude control (could also have been before navi and/or compass, they are independent) |
175 | AC_getPRTY(tempPRTY); |
172 | // AC_getRPTY(tempRPTY); |
176 | } |
173 | } |
177 | 174 | ||
178 | // Commit results to global variable and also measure control activity. |
175 | // Commit results to global variable and also measure control activity. |
179 | controls[CONTROL_THROTTLE] = tempPRTY[CONTROL_THROTTLE]; |
176 | controls[CONTROL_ROLL] = tempRPTY[CONTROL_ROLL]; |
180 | controls[CONTROL_PITCH] = tempPRTY[CONTROL_PITCH]; |
177 | controls[CONTROL_PITCH] = tempRPTY[CONTROL_PITCH]; |
181 | controls[CONTROL_ROLL] = tempPRTY[CONTROL_ROLL]; |
178 | controls[CONTROL_THROTTLE] = tempRPTY[CONTROL_THROTTLE]; |
182 | controls[CONTROL_YAW] = tempPRTY[CONTROL_YAW]; |
179 | controls[CONTROL_YAW] = tempRPTY[CONTROL_YAW]; |
- | 180 | ||
183 | // dampenControlActivity(); |
181 | debugOut.analog[14] =controls[CONTROL_ROLL]; |
- | 182 | debugOut.analog[15] =controls[CONTROL_PITCH]; |
|
184 | 183 | ||
185 | // We can safely do this even with a bad signal - the variables will not have been updated then. |
184 | // We can safely do this even with a bad signal - the variables will not have been updated then. |
186 | configuration_applyVariablesToParams(); |
185 | configuration_applyVariablesToParams(); |
187 | } |
186 | } |
188 | 187 |