Rev 838 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 838 | Rev 966 | ||
---|---|---|---|
Line 10... | Line 10... | ||
10 | Please note: The software is based on the framework provided by H. Buss and I. Busker in their Mikrokopter projekt. All functions that |
10 | Please note: The software is based on the framework provided by H. Buss and I. Busker in their Mikrokopter projekt. All functions that |
11 | are not written by Michael Walter are under the license by H. Buss and I. Busker (license_buss.txt) published by www.mikrokopter.de |
11 | are not written by Michael Walter are under the license by H. Buss and I. Busker (license_buss.txt) published by www.mikrokopter.de |
12 | unless it is stated otherwise. |
12 | unless it is stated otherwise. |
13 | */ |
13 | */ |
Line -... | Line 14... | ||
- | 14 | ||
- | 15 | /***************************************************************************** |
|
- | 16 | INCLUDES |
|
14 | 17 | **************************************************************************** */ |
|
15 | #include "main.h" |
18 | #include "main.h" |
16 | #include "kafi.h" |
- | |
17 | 19 | #include "kafi.h" |
|
18 | #include "mymath.h" |
20 | #include "mymath.h" |
Line -... | Line 21... | ||
- | 21 | #include <math.h> |
|
- | 22 | ||
- | 23 | /***************************************************************************** |
|
- | 24 | (SYMBOLIC) CONSTANTS |
|
- | 25 | *****************************************************************************/ |
|
- | 26 | ||
- | 27 | /***************************************************************************** |
|
- | 28 | VARIABLES |
|
19 | #include <math.h> |
29 | *****************************************************************************/ |
20 | 30 | ||
21 | int GPSTracking = 0; |
31 | int GPSTracking = 0; |
- | 32 | int targetPosValid = 0; |
|
Line 22... | Line 33... | ||
22 | int targetPosValid = 0; |
33 | int homePosValid = 0; |
23 | int homePosValid = 0; |
- | |
24 | 34 | int holdPosValid = 0; |
|
25 | uint8_t gpsState; |
35 | |
26 | 36 | volatile gpsInfo_t actualPos;// measured position (last gps record) |
|
Line 27... | Line 37... | ||
27 | gpsInfo_t actualPos; // measured position (last gps record) |
37 | volatile gpsInfo_t targetPos;// measured position (last gps record) |
28 | gpsInfo_t targetPos; // measured position (last gps record) |
38 | volatile gpsInfo_t homePos;// measured position (last gps record) |
29 | gpsInfo_t homePos; // measured position (last gps record) |
39 | volatile gpsInfo_t holdPos; // measured position (last gps record) |
30 | 40 | ||
Line -... | Line 41... | ||
- | 41 | NAV_STATUS_t navStatus; |
|
- | 42 | NAV_POSLLH_t navPosLlh; |
|
31 | NAV_STATUS_t navStatus; |
43 | NAV_POSUTM_t navPosUtm; |
32 | NAV_POSLLH_t navPosLlh; |
44 | NAV_VELNED_t navVelNed; |
Line 33... | Line 45... | ||
33 | NAV_POSUTM_t navPosUtm; |
45 | |
34 | NAV_VELNED_t navVelNed; |
46 | uint8_t gpsState; |
Line 42... | Line 54... | ||
42 | long velocityEW = 0; |
54 | long velocityEW = 0; |
43 | unsigned long maxDistance = 0; |
55 | unsigned long maxDistance = 0; |
Line 44... | Line 56... | ||
44 | 56 | ||
45 | int roll_gain = 0; |
57 | int roll_gain = 0; |
46 | int nick_gain = 0; |
58 | int nick_gain = 0; |
47 | int nick_gain_p = 0; |
- | |
48 | int nick_gain_d = 0; |
59 | int nick_gain_p, nick_gain_d; |
49 | int roll_gain_p = 0; |
- | |
50 | int roll_gain_d = 0; |
60 | int roll_gain_p, roll_gain_d; |
51 | int Override = 0; |
61 | int Override = 0; |
Line 52... | Line 62... | ||
52 | int TargetGier = 0; |
62 | int TargetGier = 0; |
- | 63 | ||
Line 53... | Line 64... | ||
53 | 64 | extern int sollGier; |
|
54 | extern int sollGier; |
65 | extern int RemoteLinkLost; |
55 | 66 | ||
56 | char *ubxP, *ubxEp, *ubxSp; // pointers to packet currently transfered |
67 | volatile char*ubxP, *ubxEp, *ubxSp;// pointers to packet currently transfered |
57 | uint8_t CK_A, CK_B; // UBX checksum bytes |
68 | volatile uint8_t CK_A, CK_B;// UBX checksum bytes |
Line 58... | Line 69... | ||
58 | uint8_t ignorePacket; // true when previous packet was not processed |
69 | volatile uint8_t ignorePacket;// true when previous packet was not processed |
59 | unsigned short msgLen; |
70 | volatile unsigned short msgLen; |
60 | uint8_t msgID; |
- | |
- | 71 | volatile uint8_t msgID; |
|
Line 61... | Line 72... | ||
61 | 72 | ||
62 | void GPSscanData (void); |
73 | void GPSscanData (void); |
63 | void GPSupdate(void); |
74 | void GPSupdate(void); |
Line -... | Line 75... | ||
- | 75 | void SetNewHeading(unsigned long maxDistance); |
|
- | 76 | ||
64 | 77 | /* **************************************************************************** |
|
65 | 78 | Functionname: GPSupdate */ /*! |
|
66 | /* **************************************************************************** |
79 | Description: |
67 | Functionname: GPSupdate */ /*! |
80 | |
68 | Description: |
81 | @param[in] |
69 | 82 | ||
70 | @return void |
83 | @return void |
71 | @pre - |
84 | @pre - |
72 | @post - |
85 | @post - |
73 | @author Michael Walter |
86 | @author Michael Walter |
- | 87 | **************************************************************************** */ |
|
- | 88 | void GPSupdate(void) |
|
- | 89 | { |
|
- | 90 | float SIN_H, COS_H; |
|
- | 91 | long max_p = 0; |
|
- | 92 | long max_d = 0; |
|
- | 93 | int SwitchPos = 0; |
|
- | 94 | ||
- | 95 | /* Determine Selector Switch Position */ |
|
- | 96 | if (PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] < -100) |
|
- | 97 | { |
|
- | 98 | SwitchPos = 0; |
|
- | 99 | } |
|
- | 100 | else if (PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] > 100) |
|
- | 101 | { |
|
Line -... | Line 102... | ||
- | 102 | SwitchPos = 2;/* Target Mode */ |
|
74 | **************************************************************************** */ |
103 | } |
75 | void GPSupdate(void) |
104 | else |
76 | { |
105 | { |
77 | float SIN_H, COS_H; |
106 | SwitchPos = 1;/* Position Hold */ |
78 | long max_p = 0; |
107 | } |
79 | long max_d = 0; |
108 | |
80 | 109 | /* Overide On / Off */ |
|
81 | if (abs(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]])> 15 || |
110 | if (abs(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]])> 10 || |
Line 91... | Line 120... | ||
91 | 120 | ||
92 | /* Set Home Position */ |
121 | /* Set Home Position */ |
93 | if ((actualPos.state > 2) && |
122 | if ((actualPos.state > 2) && |
94 | (homePosValid == 0)) |
123 | (homePosValid == 0)) |
95 | { |
- | |
96 | /* Save Current Position */ |
124 | { |
97 | homePos.north = actualPos.north; |
125 | homePos.north = actualPos.north; |
98 | homePos.east = actualPos.east; |
126 | homePos.east = actualPos.east; |
99 | homePos.altitude = actualPos.altitude ; |
127 | homePos.altitude = actualPos.altitude ; |
100 | homePosValid = 1; |
128 | homePosValid = 1; |
Line 101... | Line 129... | ||
101 | } |
129 | } |
102 | 130 | ||
103 | /* Set Target Position */ |
131 | /* Set Target Position */ |
104 | if ((actualPos.state > 2) && |
132 | if ((actualPos.state > 2) && |
105 | (PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] < -100)) |
- | |
106 | { |
133 | (SwitchPos == 0)) |
107 | /* Save Current Position */ |
134 | { |
108 | targetPos.north = actualPos.north; |
135 | targetPos.north = actualPos.north; |
109 | targetPos.east = actualPos.east; |
136 | targetPos.east = actualPos.east; |
- | 137 | targetPos.altitude = actualPos.altitude ; |
|
- | 138 | targetPosValid = 1; |
|
- | 139 | } |
|
- | 140 | if ((actualPos.state < 3) && |
|
- | 141 | (SwitchPos == 0)) |
|
- | 142 | { |
|
Line -... | Line 143... | ||
- | 143 | targetPosValid = 0; |
|
- | 144 | } |
|
- | 145 | ||
- | 146 | /* Set Hold Position */ |
|
- | 147 | if ((actualPos.state > 2) && |
|
- | 148 | ((Override == 1) || |
|
- | 149 | (SwitchPos == 2) )) /* Update the hold position in case we are in target mode */ |
|
- | 150 | { |
|
- | 151 | holdPos.north = actualPos.north; |
|
- | 152 | holdPos.east = actualPos.east; |
|
- | 153 | holdPos.altitude = actualPos.altitude ; |
|
- | 154 | holdPosValid = 1; |
|
- | 155 | } |
|
- | 156 | if ((actualPos.state < 3) && |
|
- | 157 | (Override == 1)) |
|
- | 158 | { |
|
- | 159 | holdPosValid = 0; |
|
- | 160 | } |
|
- | 161 | ||
- | 162 | /* Indicate Valid GPS Position */ |
|
110 | targetPos.altitude = actualPos.altitude ; |
163 | if ((actualPos.state > 2) && |
111 | targetPosValid = 1; |
164 | (SwitchPos == 0)) |
112 | 165 | { |
|
113 | if(BeepMuster == 0xffff) |
166 | if(BeepMuster == 0xffff) |
114 | { |
167 | { |
115 | beeptime = 5000; |
168 | beeptime = 5000; |
Line 116... | Line -... | ||
116 | BeepMuster = 0x0100; |
- | |
117 | } |
169 | BeepMuster = 0x0100; |
118 | } |
170 | } |
119 | - | ||
120 | if ((GPSTracking == 1) && |
171 | } |
121 | (PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] < 100)) |
172 | |
122 | { |
173 | if (RemoteLinkLost == 0) /* Disable Heading Update in case we lost the RC - Link */ |
123 | GPSTracking = 0; |
174 | { |
124 | beeptime = 5000; |
- | |
125 | BeepMuster = 0x0080; |
- | |
126 | } |
- | |
127 | - | ||
128 | /* The System is in Tracking State*/ |
- | |
129 | if ((GPSTracking == 0) && |
175 | max_p = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 170)) / 20); |
130 | (targetPosValid == 1) && |
176 | max_d = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 170)) / 40); |
131 | (PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] > 100) && |
177 | } |
132 | (actualPos.state > 2)) |
- | |
133 | { |
178 | else |
Line 134... | Line 179... | ||
134 | GPSTracking = 1; |
179 | { |
- | 180 | max_p = 8; |
|
135 | beeptime = 5000; |
181 | max_d = 4; |
Line 136... | Line -... | ||
136 | BeepMuster = 0x0c00; |
- | |
137 | } |
182 | } |
138 | 183 | ||
139 | max_p = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 170)) / 20); |
- | |
Line 140... | Line 184... | ||
140 | max_d = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 170)) / 40); |
184 | /* Those seem to be good values */ |
141 | 185 | max_p = 8; |
|
142 | #if 0 |
186 | max_d = 4; |
Line 143... | Line 187... | ||
143 | DebugOut.Analog[11] = max_p; |
187 | |
144 | DebugOut.Analog[12] = max_d; |
188 | //DebugOut.Analog[11] = max_p; |
145 | #endif |
189 | //DebugOut.Analog[12] = max_d; |
146 | 190 | ||
147 | static int GPSTrackingCycles = 0; |
191 | static int GPSTrackingCycles = 0; |
148 | long maxGainPos = 140; |
192 | long maxGainPos = 140; |
149 | long maxGainVel = 140; |
193 | long maxGainVel = 140; |
Line -... | Line 194... | ||
- | 194 | ||
150 | 195 | /* Ramp up gain */ |
|
151 | /* Slowly ramp up gain */ |
196 | if (GPSTrackingCycles < 1000) |
- | 197 | { |
|
- | 198 | GPSTrackingCycles++; |
|
- | 199 | } |
|
- | 200 | maxGainPos = (maxGainPos * GPSTrackingCycles) / 1000; |
|
- | 201 | maxGainVel = (maxGainVel * GPSTrackingCycles) / 1000; |
|
152 | if (GPSTrackingCycles < 1000) |
202 | |
153 | { |
203 | /* Determine Offset from nominal Position */ |
154 | GPSTrackingCycles++; |
204 | if (actualPos.state > 2 ) |
155 | } |
205 | { |
156 | maxGainPos = (maxGainPos * GPSTrackingCycles) / 1000; |
206 | if ((SwitchPos == 2) && |
- | 207 | (targetPosValid == 1) && |
|
- | 208 | (RemoteLinkLost == 0) && |
|
- | 209 | (Override == 0)) |
|
- | 210 | { /* determine distance from target position */ |
|
- | 211 | distanceNS = actualPos.north - targetPos.north; // in 0.1m |
|
- | 212 | distanceEW = actualPos.east - targetPos.east; // in 0.1m |
|
- | 213 | velocityNS = actualPos.velNorth; // in 0.1m/s |
|
- | 214 | velocityEW = actualPos.velEast; // in 0.1m/s |
|
- | 215 | maxDistance = sqrt(distanceNS * distanceNS + distanceEW * distanceEW); |
|
- | 216 | } |
|
- | 217 | else if ((SwitchPos == 1)&& |
|
- | 218 | (holdPosValid == 1) && |
|
- | 219 | (RemoteLinkLost == 0) && |
|
- | 220 | (Override == 0)) |
|
- | 221 | { /* determine distance from hold position */ |
|
- | 222 | distanceNS = actualPos.north - holdPos.north; // in 0.1m |
|
- | 223 | distanceEW = actualPos.east - holdPos.east; // in 0.1m |
|
- | 224 | velocityNS = actualPos.velNorth; // in 0.1m/s |
|
- | 225 | velocityEW = actualPos.velEast; // in 0.1m/s |
|
- | 226 | maxDistance = sqrt(distanceNS * distanceNS + distanceEW * distanceEW); |
|
- | 227 | } |
|
- | 228 | else if ((RemoteLinkLost == 1) && |
|
- | 229 | (homePosValid ==1)) /* determine distance from target position */ |
|
- | 230 | {/* Overide in case the remote link got lost */ |
|
- | 231 | distanceNS = actualPos.north - homePos.north; // in 0.1m |
|
- | 232 | distanceEW = actualPos.east - homePos.east; // in 0.1m |
|
- | 233 | velocityNS = actualPos.velNorth; // in 0.1m/s |
|
- | 234 | velocityEW = actualPos.velEast; // in 0.1m/s |
|
- | 235 | maxDistance = sqrt(distanceNS * distanceNS + distanceEW * distanceEW); |
|
- | 236 | } |
|
Line 157... | Line 237... | ||
157 | maxGainVel = (maxGainVel * GPSTrackingCycles) / 1000; |
237 | else |
158 | 238 | { |
|
159 | if (actualPos.state > 2 ) |
239 | distanceNS = 0.0F; // in 0.1m |
160 | { |
240 | distanceEW = 0.0F; // in 0.1m |
161 | distanceNS = actualPos.north - targetPos.north; // in 0.1m |
241 | velocityNS = 0.0F; // in 0.1m/s |
162 | distanceEW = actualPos.east - targetPos.east; // in 0.1m |
- | |
163 | velocityNS = actualPos.velNorth; // in 0.1m/s |
242 | velocityEW = 0.0F; // in 0.1m/s |
164 | velocityEW = actualPos.velEast; // in 0.1m/s |
- | |
Line 165... | Line 243... | ||
165 | maxDistance = sqrt(distanceNS * distanceNS + distanceEW * distanceEW); |
243 | maxDistance = 0.0F; |
166 | 244 | GPSTrackingCycles = 0; |
|
167 | // Limit GPS_Nick to 25 |
245 | } |
168 | nick_gain_p = (long) MAX(-maxGainPos, MIN(maxGainPos, ((distanceNS* max_p)/50))); //m |
246 | |
169 | nick_gain_d = (long) MAX(-maxGainVel, MIN(maxGainVel, ((actualPos.velNorth * max_d)/50))); //m/s |
247 | /* Limit GPS_Nick to 25 */ |
170 | roll_gain_p = (long) MAX(-maxGainPos, MIN(maxGainPos, ((distanceEW * max_p)/50))); //m |
248 | nick_gain_p = (long) MAX(-maxGainPos, MIN(maxGainPos, ((distanceNS* max_p)/50))); //m |
171 | roll_gain_d = (long) MAX(-maxGainVel, MIN(maxGainVel, ((actualPos.velEast * max_d)/50))); //m/s |
249 | nick_gain_d = (long) MAX(-maxGainVel, MIN(maxGainVel, ((velocityNS * max_d)/50))); //m/s |
Line 172... | Line -... | ||
172 | - | ||
173 | TargetGier = c_atan2(-distanceEW / 8, -distanceNS / 8) * 10; |
- | |
174 | } |
- | |
175 | - | ||
176 | if ((GPSTracking == 1) && |
250 | roll_gain_p = (long) MAX(-maxGainPos, MIN(maxGainPos, ((distanceEW * max_p)/50))); //m |
177 | (actualPos.state > 2) && |
251 | roll_gain_d = (long) MAX(-maxGainVel, MIN(maxGainVel, ((velocityEW * max_d)/50))); //m/s |
Line 178... | Line 252... | ||
178 | (Override == 0)) |
252 | TargetGier = c_atan2(-distanceEW / 8, -distanceNS / 8) * 10; |
179 | { |
253 | |
Line 180... | Line -... | ||
180 | /* Calculate Distance to Target */ |
- | |
181 | SIN_H = (float) sin(status.Psi); |
- | |
182 | COS_H =(float) cos(status.Psi); |
- | |
183 | - | ||
184 | /* PD-Regler */ |
- | |
185 | nick_gain = nick_gain_p + nick_gain_d; |
- | |
186 | roll_gain = -(roll_gain_p + roll_gain_d); |
- | |
187 | - | ||
188 | GPS_Nick = (int) (COS_H * (float) nick_gain - SIN_H * (float) roll_gain); |
- | |
189 | GPS_Roll = (int) (SIN_H * (float) nick_gain + COS_H * (float) roll_gain); |
- | |
190 | - | ||
191 | GPS_Nick = MAX(-maxGainPos, MIN(maxGainPos, GPS_Nick)); |
- | |
192 | GPS_Roll = MAX(-maxGainPos, MIN(maxGainPos, GPS_Roll)); |
- | |
193 | - | ||
194 | /* Turn the mikrokopter slowly towards the target position */ |
254 | /* PD-Control */ |
195 | { |
- | |
196 | int OffsetGier; |
- | |
197 | if (maxDistance / 10 > 2) |
- | |
198 | { |
- | |
199 | OffsetGier = 2; |
- | |
200 | } |
255 | nick_gain = nick_gain_p + nick_gain_d; |
201 | else |
256 | roll_gain = -(roll_gain_p + roll_gain_d); |
202 | { |
257 | |
203 | OffsetGier = 0; |
258 | /* Calculate Distance to Target */ |
204 | } |
259 | SIN_H = (float) sin(status.Psi); |
205 | - | ||
206 | if (TargetGier < 0) |
- | |
207 | { |
- | |
208 | TargetGier += 3600; |
- | |
209 | } |
- | |
210 | if (TargetGier > sollGier) |
- | |
211 | { |
260 | COS_H =(float) cos(status.Psi); |
212 | if (TargetGier - sollGier < 1800) |
- | |
213 | { |
- | |
214 | sollGier += OffsetGier; |
- | |
215 | } |
261 | |
216 | else |
- | |
217 | { |
262 | GPS_Nick = (int) (COS_H * (float) nick_gain - SIN_H * (float) roll_gain); |
218 | sollGier -= OffsetGier; |
263 | GPS_Roll = (int) (SIN_H * (float) nick_gain + COS_H * (float) roll_gain); |
- | 264 | ||
- | 265 | GPS_Nick = MAX(-maxGainPos, MIN(maxGainPos, GPS_Nick)); |
|
219 | } |
266 | GPS_Roll = MAX(-maxGainPos, MIN(maxGainPos, GPS_Roll)); |
220 | } |
- | |
221 | else |
267 | |
222 | { |
268 | /* Set New Heading */ |
223 | if (sollGier - TargetGier < 1800) |
269 | SetNewHeading(maxDistance); |
224 | { |
270 | } |
225 | sollGier -= OffsetGier; |
271 | else |
226 | } |
272 | { |
Line 267... | Line 313... | ||
267 | } |
313 | } |
268 | beeptime = 5000; |
314 | beeptime = 5000; |
269 | BeepMuster = 0x0c00; |
315 | BeepMuster = 0x0c00; |
270 | } |
316 | } |
271 | #endif |
317 | #endif |
- | 318 | ||
- | 319 | ||
- | 320 | void SetNewHeading(unsigned long maxDistance) |
|
- | 321 | /* Set New Heading */ |
|
- | 322 | { |
|
- | 323 | int OffsetGier = 0; |
|
- | 324 | if (maxDistance / 10 > 8) |
|
- | 325 | { |
|
- | 326 | OffsetGier = 4; |
|
- | 327 | } |
|
- | 328 | ||
- | 329 | if (TargetGier < 0) |
|
- | 330 | { |
|
- | 331 | TargetGier += 3600; |
|
- | 332 | } |
|
- | 333 | if (TargetGier > sollGier) |
|
- | 334 | { |
|
- | 335 | if (TargetGier - sollGier < 1800) |
|
- | 336 | { |
|
- | 337 | sollGier += OffsetGier; |
|
272 | } |
338 | } |
273 | else |
339 | else |
274 | { |
340 | { |
275 | GPS_Nick = 0; |
341 | sollGier -= OffsetGier; |
- | 342 | } |
|
- | 343 | } |
|
- | 344 | else |
|
- | 345 | { |
|
- | 346 | if (sollGier - TargetGier < 1800) |
|
- | 347 | { |
|
276 | GPS_Roll = 0; |
348 | sollGier -= OffsetGier; |
- | 349 | } |
|
- | 350 | else |
|
- | 351 | { |
|
277 | GPSTrackingCycles = 0; |
352 | sollGier += OffsetGier; |
- | 353 | } |
|
278 | } |
354 | } |
279 | } |
355 | } |
Line 280... | Line 356... | ||
280 | 356 | ||
281 | /* **************************************************************************** |
357 | /* **************************************************************************** |