Rev 838 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 838 | Rev 966 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | Copyright 2008, by Michael Walter |
2 | Copyright 2008, by Michael Walter |
3 | 3 | ||
4 | All functions written by Michael Walter are free software and can be redistributed and/or modified under the terms of the GNU Lesser |
4 | All functions written by Michael Walter are free software and can be redistributed and/or modified under the terms of the GNU Lesser |
5 | General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but |
5 | General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but |
6 | WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
6 | WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
7 | See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public |
7 | See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public |
8 | License along with this program. If not, see <http://www.gnu.org/licenses/>. |
8 | License along with this program. If not, see <http://www.gnu.org/licenses/>. |
9 | 9 | ||
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 | */ |
- | 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" |
19 | #include <math.h> |
21 | #include <math.h> |
- | 22 | ||
- | 23 | /***************************************************************************** |
|
- | 24 | (SYMBOLIC) CONSTANTS |
|
- | 25 | *****************************************************************************/ |
|
- | 26 | ||
- | 27 | /***************************************************************************** |
|
- | 28 | VARIABLES |
|
- | 29 | *****************************************************************************/ |
|
20 | 30 | ||
21 | int GPSTracking = 0; |
31 | int GPSTracking = 0; |
22 | int targetPosValid = 0; |
32 | int targetPosValid = 0; |
23 | int homePosValid = 0; |
33 | int homePosValid = 0; |
- | 34 | int holdPosValid = 0; |
|
24 | 35 | ||
25 | uint8_t gpsState; |
- | |
26 | 36 | volatile gpsInfo_t actualPos;// measured position (last gps record) |
|
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 | ||
31 | NAV_STATUS_t navStatus; |
41 | NAV_STATUS_t navStatus; |
32 | NAV_POSLLH_t navPosLlh; |
42 | NAV_POSLLH_t navPosLlh; |
33 | NAV_POSUTM_t navPosUtm; |
43 | NAV_POSUTM_t navPosUtm; |
34 | NAV_VELNED_t navVelNed; |
44 | NAV_VELNED_t navVelNed; |
- | 45 | ||
- | 46 | uint8_t gpsState; |
|
35 | 47 | ||
36 | signed int GPS_Nick = 0; |
48 | signed int GPS_Nick = 0; |
37 | signed int GPS_Roll = 0; |
49 | signed int GPS_Roll = 0; |
38 | 50 | ||
39 | long distanceNS = 0; |
51 | long distanceNS = 0; |
40 | long distanceEW = 0; |
52 | long distanceEW = 0; |
41 | long velocityNS = 0; |
53 | long velocityNS = 0; |
42 | long velocityEW = 0; |
54 | long velocityEW = 0; |
43 | unsigned long maxDistance = 0; |
55 | unsigned long maxDistance = 0; |
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; |
59 | int nick_gain_p, nick_gain_d; |
48 | int nick_gain_d = 0; |
- | |
49 | int roll_gain_p = 0; |
60 | int roll_gain_p, roll_gain_d; |
50 | int roll_gain_d = 0; |
- | |
51 | int Override = 0; |
61 | int Override = 0; |
52 | int TargetGier = 0; |
62 | int TargetGier = 0; |
53 | 63 | ||
54 | extern int sollGier; |
64 | 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 |
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; |
61 | 72 | ||
62 | void GPSscanData (void); |
73 | void GPSscanData (void); |
63 | void GPSupdate(void); |
74 | void GPSupdate(void); |
64 | - | ||
- | 75 | void SetNewHeading(unsigned long maxDistance); |
|
65 | 76 | ||
66 | /* **************************************************************************** |
77 | /* **************************************************************************** |
67 | Functionname: GPSupdate */ /*! |
78 | Functionname: GPSupdate */ /*! |
68 | Description: |
79 | Description: |
- | 80 | ||
- | 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 |
74 | **************************************************************************** */ |
87 | **************************************************************************** */ |
75 | void GPSupdate(void) |
88 | void GPSupdate(void) |
76 | { |
89 | { |
77 | float SIN_H, COS_H; |
90 | float SIN_H, COS_H; |
78 | long max_p = 0; |
91 | long max_p = 0; |
79 | long max_d = 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 | { |
|
- | 102 | SwitchPos = 2;/* Target Mode */ |
|
- | 103 | } |
|
- | 104 | else |
|
- | 105 | { |
|
- | 106 | SwitchPos = 1;/* Position Hold */ |
|
- | 107 | } |
|
- | 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 || |
82 | abs(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]])> 10 || |
111 | abs(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]])> 10 || |
83 | abs(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]])> 15) |
112 | abs(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]])> 10) |
84 | { |
113 | { |
85 | Override = 1; |
114 | Override = 1; |
86 | } |
115 | } |
87 | else |
116 | else |
88 | { |
117 | { |
89 | Override = 0; |
118 | Override = 0; |
90 | } |
119 | } |
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 | { |
124 | { |
96 | /* Save Current Position */ |
- | |
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; |
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)) |
133 | (SwitchPos == 0)) |
106 | { |
134 | { |
107 | /* Save Current Position */ |
- | |
108 | targetPos.north = actualPos.north; |
135 | targetPos.north = actualPos.north; |
109 | targetPos.east = actualPos.east; |
136 | targetPos.east = actualPos.east; |
110 | targetPos.altitude = actualPos.altitude ; |
137 | targetPos.altitude = actualPos.altitude ; |
111 | targetPosValid = 1; |
138 | targetPosValid = 1; |
- | 139 | } |
|
- | 140 | if ((actualPos.state < 3) && |
|
- | 141 | (SwitchPos == 0)) |
|
- | 142 | { |
|
- | 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 */ |
|
- | 163 | if ((actualPos.state > 2) && |
|
- | 164 | (SwitchPos == 0)) |
|
112 | 165 | { |
|
113 | if(BeepMuster == 0xffff) |
166 | if(BeepMuster == 0xffff) |
114 | { |
167 | { |
115 | beeptime = 5000; |
168 | beeptime = 5000; |
116 | BeepMuster = 0x0100; |
169 | BeepMuster = 0x0100; |
117 | } |
170 | } |
118 | } |
171 | } |
119 | - | ||
120 | if ((GPSTracking == 1) && |
172 | |
121 | (PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] < 100)) |
173 | if (RemoteLinkLost == 0) /* Disable Heading Update in case we lost the RC - Link */ |
122 | { |
- | |
123 | GPSTracking = 0; |
174 | { |
124 | beeptime = 5000; |
175 | max_p = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 170)) / 20); |
125 | BeepMuster = 0x0080; |
176 | max_d = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 170)) / 40); |
126 | } |
177 | } |
127 | - | ||
128 | /* The System is in Tracking State*/ |
- | |
129 | if ((GPSTracking == 0) && |
- | |
130 | (targetPosValid == 1) && |
- | |
131 | (PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] > 100) && |
- | |
132 | (actualPos.state > 2)) |
178 | else |
133 | { |
179 | { |
134 | GPSTracking = 1; |
180 | max_p = 8; |
135 | beeptime = 5000; |
- | |
136 | BeepMuster = 0x0c00; |
181 | max_d = 4; |
137 | } |
182 | } |
- | 183 | ||
138 | 184 | /* Those seem to be good values */ |
|
139 | max_p = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 170)) / 20); |
- | |
140 | max_d = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 170)) / 40); |
185 | max_p = 8; |
141 | 186 | max_d = 4; |
|
142 | #if 0 |
- | |
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; |
150 | 194 | ||
151 | /* Slowly ramp up gain */ |
195 | /* Ramp up gain */ |
152 | if (GPSTrackingCycles < 1000) |
196 | if (GPSTrackingCycles < 1000) |
153 | { |
197 | { |
154 | GPSTrackingCycles++; |
198 | GPSTrackingCycles++; |
155 | } |
199 | } |
156 | maxGainPos = (maxGainPos * GPSTrackingCycles) / 1000; |
200 | maxGainPos = (maxGainPos * GPSTrackingCycles) / 1000; |
157 | maxGainVel = (maxGainVel * GPSTrackingCycles) / 1000; |
201 | maxGainVel = (maxGainVel * GPSTrackingCycles) / 1000; |
- | 202 | ||
158 | 203 | /* Determine Offset from nominal Position */ |
|
159 | if (actualPos.state > 2 ) |
204 | if (actualPos.state > 2 ) |
- | 205 | { |
|
- | 206 | if ((SwitchPos == 2) && |
|
- | 207 | (targetPosValid == 1) && |
|
- | 208 | (RemoteLinkLost == 0) && |
|
- | 209 | (Override == 0)) |
|
160 | { |
210 | { /* determine distance from target position */ |
161 | distanceNS = actualPos.north - targetPos.north; // in 0.1m |
211 | distanceNS = actualPos.north - targetPos.north; // in 0.1m |
162 | distanceEW = actualPos.east - targetPos.east; // in 0.1m |
212 | distanceEW = actualPos.east - targetPos.east; // in 0.1m |
163 | velocityNS = actualPos.velNorth; // in 0.1m/s |
213 | velocityNS = actualPos.velNorth; // in 0.1m/s |
164 | velocityEW = actualPos.velEast; // in 0.1m/s |
214 | velocityEW = actualPos.velEast; // in 0.1m/s |
165 | maxDistance = sqrt(distanceNS * distanceNS + distanceEW * distanceEW); |
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 | } |
|
- | 237 | else |
|
- | 238 | { |
|
- | 239 | distanceNS = 0.0F; // in 0.1m |
|
- | 240 | distanceEW = 0.0F; // in 0.1m |
|
- | 241 | velocityNS = 0.0F; // in 0.1m/s |
|
- | 242 | velocityEW = 0.0F; // in 0.1m/s |
|
- | 243 | maxDistance = 0.0F; |
|
- | 244 | GPSTrackingCycles = 0; |
|
- | 245 | } |
|
166 | 246 | ||
167 | // Limit GPS_Nick to 25 |
247 | /* Limit GPS_Nick to 25 */ |
168 | nick_gain_p = (long) MAX(-maxGainPos, MIN(maxGainPos, ((distanceNS* max_p)/50))); //m |
248 | nick_gain_p = (long) MAX(-maxGainPos, MIN(maxGainPos, ((distanceNS* max_p)/50))); //m |
169 | nick_gain_d = (long) MAX(-maxGainVel, MIN(maxGainVel, ((actualPos.velNorth * max_d)/50))); //m/s |
249 | nick_gain_d = (long) MAX(-maxGainVel, MIN(maxGainVel, ((velocityNS * max_d)/50))); //m/s |
170 | roll_gain_p = (long) MAX(-maxGainPos, MIN(maxGainPos, ((distanceEW * max_p)/50))); //m |
250 | roll_gain_p = (long) MAX(-maxGainPos, MIN(maxGainPos, ((distanceEW * max_p)/50))); //m |
171 | roll_gain_d = (long) MAX(-maxGainVel, MIN(maxGainVel, ((actualPos.velEast * max_d)/50))); //m/s |
- | |
172 | 251 | roll_gain_d = (long) MAX(-maxGainVel, MIN(maxGainVel, ((velocityEW * max_d)/50))); //m/s |
|
173 | TargetGier = c_atan2(-distanceEW / 8, -distanceNS / 8) * 10; |
- | |
174 | } |
252 | TargetGier = c_atan2(-distanceEW / 8, -distanceNS / 8) * 10; |
175 | 253 | ||
176 | if ((GPSTracking == 1) && |
254 | /* PD-Control */ |
177 | (actualPos.state > 2) && |
255 | nick_gain = nick_gain_p + nick_gain_d; |
178 | (Override == 0)) |
256 | roll_gain = -(roll_gain_p + roll_gain_d); |
179 | { |
257 | |
180 | /* Calculate Distance to Target */ |
258 | /* Calculate Distance to Target */ |
181 | SIN_H = (float) sin(status.Psi); |
259 | SIN_H = (float) sin(status.Psi); |
182 | COS_H =(float) cos(status.Psi); |
260 | 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 | 261 | ||
188 | GPS_Nick = (int) (COS_H * (float) nick_gain - SIN_H * (float) roll_gain); |
262 | 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); |
263 | GPS_Roll = (int) (SIN_H * (float) nick_gain + COS_H * (float) roll_gain); |
190 | 264 | ||
191 | GPS_Nick = MAX(-maxGainPos, MIN(maxGainPos, GPS_Nick)); |
265 | GPS_Nick = MAX(-maxGainPos, MIN(maxGainPos, GPS_Nick)); |
192 | GPS_Roll = MAX(-maxGainPos, MIN(maxGainPos, GPS_Roll)); |
266 | GPS_Roll = MAX(-maxGainPos, MIN(maxGainPos, GPS_Roll)); |
193 | - | ||
194 | /* Turn the mikrokopter slowly towards the target position */ |
- | |
195 | { |
- | |
196 | int OffsetGier; |
- | |
197 | if (maxDistance / 10 > 2) |
- | |
198 | { |
- | |
199 | OffsetGier = 2; |
- | |
200 | } |
- | |
201 | else |
- | |
202 | { |
- | |
203 | OffsetGier = 0; |
- | |
204 | } |
- | |
205 | - | ||
206 | if (TargetGier < 0) |
- | |
207 | { |
267 | |
208 | TargetGier += 3600; |
- | |
209 | } |
- | |
210 | if (TargetGier > sollGier) |
- | |
211 | { |
- | |
212 | if (TargetGier - sollGier < 1800) |
- | |
213 | { |
268 | /* Set New Heading */ |
214 | sollGier += OffsetGier; |
269 | SetNewHeading(maxDistance); |
215 | } |
270 | } |
216 | else |
271 | else |
217 | { |
272 | { |
218 | sollGier -= OffsetGier; |
273 | GPS_Nick = 0; |
219 | } |
- | |
220 | } |
- | |
221 | else |
- | |
222 | { |
- | |
223 | if (sollGier - TargetGier < 1800) |
- | |
224 | { |
- | |
225 | sollGier -= OffsetGier; |
274 | GPS_Roll = 0; |
226 | } |
- | |
227 | else |
- | |
228 | { |
- | |
229 | sollGier += OffsetGier; |
275 | maxDistance = 0.0F; |
230 | } |
- | |
231 | } |
276 | } |
232 | } |
277 | } |
- | 278 | ||
- | 279 | ||
233 | #if 0 |
280 | #if 0 |
234 | /* Go round in a square */ |
- | |
235 | if (maxDistance / 10 < 10) |
281 | if (maxDistance / 10 < 12) |
236 | { |
282 | { |
237 | static int iState = 0; |
283 | static int iState = 0; |
238 | switch (iState) |
284 | switch (iState) |
239 | { |
285 | { |
240 | case 0: |
286 | case 0: |
241 | targetPos.north += 400; |
287 | targetPos.north += 400; |
242 | targetPos.east += 0; |
288 | targetPos.east += 0; |
243 | GPSTrackingCycles = 0; |
289 | GPSTrackingCycles = 0; |
244 | iState++; |
290 | iState++; |
245 | break; |
291 | break; |
246 | case 1: |
292 | case 1: |
247 | targetPos.north += 0; |
293 | targetPos.north += 0; |
248 | targetPos.east += 400; |
294 | targetPos.east += 400; |
249 | GPSTrackingCycles = 0; |
295 | GPSTrackingCycles = 0; |
250 | iState++; |
296 | iState++; |
251 | break; |
297 | break; |
252 | case 2: |
298 | case 2: |
253 | targetPos.north -= 400; |
299 | targetPos.north -= 400; |
254 | targetPos.east += 0; |
300 | targetPos.east += 0; |
255 | GPSTrackingCycles = 0; |
301 | GPSTrackingCycles = 0; |
256 | iState++; |
302 | iState++; |
257 | break; |
303 | break; |
258 | case 3: |
304 | case 3: |
259 | targetPos.north += 0; |
305 | targetPos.north += 0; |
260 | targetPos.east -= 400; |
306 | targetPos.east -= 400; |
261 | GPSTrackingCycles = 0; |
307 | GPSTrackingCycles = 0; |
262 | iState=0; |
308 | iState=0; |
263 | break; |
309 | break; |
264 | default: |
310 | default: |
265 | iState=0; |
311 | iState=0; |
266 | break; |
312 | break; |
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 | } |
280 | 356 | ||
281 | /* **************************************************************************** |
357 | /* **************************************************************************** |
282 | Functionname: InitGPS */ /*! |
358 | Functionname: InitGPS */ /*! |
283 | Description: |
359 | Description: |
284 | 360 | ||
285 | @return void |
361 | @return void |
286 | @pre - |
362 | @pre - |
287 | @post - |
363 | @post - |
288 | @author |
364 | @author |
289 | **************************************************************************** */ |
365 | **************************************************************************** */ |
290 | void InitGPS(void) |
366 | void InitGPS(void) |
291 | { |
367 | { |
292 | // USART1 Control and Status Register A, B, C and baud rate register |
368 | // USART1 Control and Status Register A, B, C and baud rate register |
293 | uint8_t sreg = SREG; |
369 | uint8_t sreg = SREG; |
294 | //uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * USART1_BAUD) - 1); |
370 | //uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * USART1_BAUD) - 1); |
295 | 371 | ||
296 | // disable all interrupts before reconfiguration |
372 | // disable all interrupts before reconfiguration |
297 | cli(); |
373 | cli(); |
298 | 374 | ||
299 | // disable RX-Interrupt |
375 | // disable RX-Interrupt |
300 | UCSR1B &= ~(1 << RXCIE1); |
376 | UCSR1B &= ~(1 << RXCIE1); |
301 | // disable TX-Interrupt |
377 | // disable TX-Interrupt |
302 | UCSR1B &= ~(1 << TXCIE1); |
378 | UCSR1B &= ~(1 << TXCIE1); |
303 | // disable DRE-Interrupt |
379 | // disable DRE-Interrupt |
304 | UCSR1B &= ~(1 << UDRIE1); |
380 | UCSR1B &= ~(1 << UDRIE1); |
305 | 381 | ||
306 | // set direction of RXD1 and TXD1 pins |
382 | // set direction of RXD1 and TXD1 pins |
307 | // set RXD1 (PD2) as an input pin |
383 | // set RXD1 (PD2) as an input pin |
308 | PORTD |= (1 << PORTD2); |
384 | PORTD |= (1 << PORTD2); |
309 | DDRD &= ~(1 << DDD2); |
385 | DDRD &= ~(1 << DDD2); |
310 | 386 | ||
311 | // set TXD1 (PD3) as an output pin |
387 | // set TXD1 (PD3) as an output pin |
312 | PORTD |= (1 << PORTD3); |
388 | PORTD |= (1 << PORTD3); |
313 | DDRD |= (1 << DDD3); |
389 | DDRD |= (1 << DDD3); |
314 | 390 | ||
315 | // USART0 Baud Rate Register |
391 | // USART0 Baud Rate Register |
316 | // set clock divider |
392 | // set clock divider |
317 | UBRR1H = 0; |
393 | UBRR1H = 0; |
318 | UBRR1L = BAUDRATE; |
394 | UBRR1L = BAUDRATE; |
319 | 395 | ||
320 | // enable double speed operation |
396 | // enable double speed operation |
321 | //UCSR1A |= (1 << U2X1); |
397 | //UCSR1A |= (1 << U2X1); |
322 | UCSR1A = _B0(U2X1); |
398 | UCSR1A = _B0(U2X1); |
323 | 399 | ||
324 | // enable receiver and transmitter |
400 | // enable receiver and transmitter |
325 | UCSR1B = (1 << TXEN1) | (1 << RXEN1); |
401 | UCSR1B = (1 << TXEN1) | (1 << RXEN1); |
326 | // set asynchronous mode |
402 | // set asynchronous mode |
327 | UCSR1C &= ~(1 << UMSEL11); |
403 | UCSR1C &= ~(1 << UMSEL11); |
328 | UCSR1C &= ~(1 << UMSEL10); |
404 | UCSR1C &= ~(1 << UMSEL10); |
329 | // no parity |
405 | // no parity |
330 | UCSR1C &= ~(1 << UPM11); |
406 | UCSR1C &= ~(1 << UPM11); |
331 | UCSR1C &= ~(1 << UPM10); |
407 | UCSR1C &= ~(1 << UPM10); |
332 | // 1 stop bit |
408 | // 1 stop bit |
333 | UCSR1C &= ~(1 << USBS1); |
409 | UCSR1C &= ~(1 << USBS1); |
334 | // 8-bit |
410 | // 8-bit |
335 | UCSR1B &= ~(1 << UCSZ12); |
411 | UCSR1B &= ~(1 << UCSZ12); |
336 | UCSR1C |= (1 << UCSZ11); |
412 | UCSR1C |= (1 << UCSZ11); |
337 | UCSR1C |= (1 << UCSZ10); |
413 | UCSR1C |= (1 << UCSZ10); |
338 | 414 | ||
339 | // flush receive buffer explicit |
415 | // flush receive buffer explicit |
340 | while ( UCSR1A & (1<<RXC1) ) UDR1; |
416 | while ( UCSR1A & (1<<RXC1) ) UDR1; |
341 | 417 | ||
342 | // enable interrupts at the end |
418 | // enable interrupts at the end |
343 | // enable RX-Interrupt |
419 | // enable RX-Interrupt |
344 | UCSR1B |= (1 << RXCIE1); |
420 | UCSR1B |= (1 << RXCIE1); |
345 | // enable TX-Interrupt |
421 | // enable TX-Interrupt |
346 | UCSR1B |= (1 << TXCIE1); |
422 | UCSR1B |= (1 << TXCIE1); |
347 | // enable DRE interrupt |
423 | // enable DRE interrupt |
348 | //UCSR1B |= (1 << UDRIE1); |
424 | //UCSR1B |= (1 << UDRIE1); |
349 | 425 | ||
350 | // restore global interrupt flags |
426 | // restore global interrupt flags |
351 | SREG = sreg; |
427 | SREG = sreg; |
352 | 428 | ||
353 | gpsState = GPS_EMPTY; |
429 | gpsState = GPS_EMPTY; |
354 | } |
430 | } |
355 | 431 | ||
356 | 432 | ||
357 | /* **************************************************************************** |
433 | /* **************************************************************************** |
358 | Functionname: InitGPS */ /*! |
434 | Functionname: InitGPS */ /*! |
359 | Description: Copy GPS paket data to actualPos |
435 | Description: Copy GPS paket data to actualPos |
360 | 436 | ||
361 | @return void |
437 | @return void |
362 | @pre - |
438 | @pre - |
363 | @post - |
439 | @post - |
364 | @author |
440 | @author |
365 | **************************************************************************** */ |
441 | **************************************************************************** */ |
366 | void GPSscanData (void) |
442 | void GPSscanData (void) |
367 | { |
443 | { |
368 | if (navStatus.packetStatus == 1) // valid packet |
444 | if (navStatus.packetStatus == 1)// valid packet |
369 | { |
445 | { |
370 | actualPos.state = navStatus.GPSfix; |
446 | actualPos.state = navStatus.GPSfix; |
371 | if ((actualPos.state > 1) && (GPSTracking == 0)) |
447 | if ((actualPos.state > 1) && (GPSTracking == 0)) |
372 | { |
448 | { |
373 | GRN_FLASH; |
449 | GRN_FLASH; |
374 | } |
450 | } |
375 | navStatus.packetStatus = 0; |
451 | navStatus.packetStatus = 0; |
376 | } |
452 | } |
377 | 453 | ||
378 | if (navPosUtm.packetStatus == 1) // valid packet |
454 | if (navPosUtm.packetStatus == 1)// valid packet |
379 | { |
455 | { |
380 | actualPos.north = navPosUtm.NORTH/10L; |
456 | actualPos.north = navPosUtm.NORTH/10L; |
381 | actualPos.east = navPosUtm.EAST/10L; |
457 | actualPos.east = navPosUtm.EAST/10L; |
382 | actualPos.altitude = navPosUtm.ALT/100; |
458 | actualPos.altitude = navPosUtm.ALT/100; |
383 | actualPos.ITOW = navPosUtm.ITOW; |
459 | actualPos.ITOW = navPosUtm.ITOW; |
384 | navPosUtm.packetStatus = 0; |
460 | navPosUtm.packetStatus = 0; |
385 | } |
461 | } |
386 | /* |
462 | /* |
387 | if (navPosLlh.packetStatus == 1) |
463 | if (navPosLlh.packetStatus == 1) |
388 | { |
464 | { |
389 | actualPos.longi = navPosLlh.LON; |
465 | actualPos.longi = navPosLlh.LON; |
390 | actualPos.lati = navPosLlh.LAT; |
466 | actualPos.lati = navPosLlh.LAT; |
391 | actualPos.height = navPosLlh.HEIGHT; |
467 | actualPos.height = navPosLlh.HEIGHT; |
392 | navPosLlh.packetStatus = 0; |
468 | navPosLlh.packetStatus = 0; |
393 | } |
469 | } |
394 | */ |
470 | */ |
395 | if (navVelNed.packetStatus == 1) |
471 | if (navVelNed.packetStatus == 1) |
396 | { |
472 | { |
397 | actualPos.velNorth = navVelNed.VEL_N; |
473 | actualPos.velNorth = navVelNed.VEL_N; |
398 | actualPos.velEast = navVelNed.VEL_E; |
474 | actualPos.velEast = navVelNed.VEL_E; |
399 | actualPos.velDown = navVelNed.VEL_D; |
475 | actualPos.velDown = navVelNed.VEL_D; |
400 | actualPos.groundSpeed = navVelNed.GSpeed; |
476 | actualPos.groundSpeed = navVelNed.GSpeed; |
401 | navVelNed.packetStatus = 0; |
477 | navVelNed.packetStatus = 0; |
402 | } |
478 | } |
403 | } |
479 | } |
404 | 480 | ||
405 | /* **************************************************************************** |
481 | /* **************************************************************************** |
406 | Functionname: SIGNAL */ /*! |
482 | Functionname: SIGNAL */ /*! |
407 | Description: |
483 | Description: |
408 | 484 | ||
409 | @return void |
485 | @return void |
410 | @pre - |
486 | @pre - |
411 | @post - |
487 | @post - |
412 | @author |
488 | @author |
413 | **************************************************************************** */ |
489 | **************************************************************************** */ |
414 | SIGNAL (SIG_USART1_RECV) |
490 | SIGNAL (SIG_USART1_RECV) |
415 | { |
491 | { |
416 | uint8_t c; |
492 | uint8_t c; |
417 | uint8_t re; |
493 | uint8_t re; |
418 | 494 | ||
419 | re = (UCSR1A & (_B1(FE1) | _B1(DOR1))); // any error occured ? |
495 | re = (UCSR1A & (_B1(FE1) | _B1(DOR1)));// any error occured ? |
420 | c = UDR1; |
496 | c = UDR1; |
421 | 497 | ||
422 | if (re == 0) |
498 | if (re == 0) |
423 | { |
499 | { |
424 | switch (gpsState) |
500 | switch (gpsState) |
425 | { |
501 | { |
426 | case GPS_EMPTY: |
502 | case GPS_EMPTY: |
427 | if (c == SYNC_CHAR1) |
503 | if (c == SYNC_CHAR1) |
428 | { |
504 | { |
429 | gpsState = GPS_SYNC1; |
505 | gpsState = GPS_SYNC1; |
430 | } |
506 | } |
431 | break; |
507 | break; |
432 | case GPS_SYNC1: |
508 | case GPS_SYNC1: |
433 | if (c == SYNC_CHAR2) |
509 | if (c == SYNC_CHAR2) |
434 | { |
510 | { |
435 | gpsState = GPS_SYNC2; |
511 | gpsState = GPS_SYNC2; |
436 | } |
512 | } |
437 | else if (c != SYNC_CHAR1) |
513 | else if (c != SYNC_CHAR1) |
438 | { |
514 | { |
439 | gpsState = GPS_EMPTY; |
515 | gpsState = GPS_EMPTY; |
440 | } |
516 | } |
441 | break; |
517 | break; |
442 | case GPS_SYNC2: |
518 | case GPS_SYNC2: |
443 | if (c == CLASS_NAV) |
519 | if (c == CLASS_NAV) |
444 | { |
520 | { |
445 | gpsState = GPS_CLASS; |
521 | gpsState = GPS_CLASS; |
446 | } |
522 | } |
447 | else |
523 | else |
448 | { |
524 | { |
449 | gpsState = GPS_EMPTY; |
525 | gpsState = GPS_EMPTY; |
450 | } |
526 | } |
451 | break; |
527 | break; |
452 | case GPS_CLASS: // msg ID seen: init packed receive |
528 | case GPS_CLASS:// msg ID seen: init packed receive |
453 | msgID = c; |
529 | msgID = c; |
454 | CK_A = CLASS_NAV + c; |
530 | CK_A = CLASS_NAV + c; |
455 | CK_B = CLASS_NAV + CK_A; |
531 | CK_B = CLASS_NAV + CK_A; |
456 | gpsState = GPS_LEN1; |
532 | gpsState = GPS_LEN1; |
457 | 533 | ||
458 | switch (msgID) |
534 | switch (msgID) |
459 | { |
535 | { |
460 | case MSGID_STATUS: |
536 | case MSGID_STATUS: |
461 | ubxP = (char*)&navStatus; |
537 | ubxP = (char*)&navStatus; |
462 | ubxEp = (char*)(&navStatus + sizeof(NAV_STATUS_t)); |
538 | ubxEp = (char*)(&navStatus + sizeof(NAV_STATUS_t)); |
463 | ubxSp = (char*)&navStatus.packetStatus; |
539 | ubxSp = (char*)&navStatus.packetStatus; |
464 | ignorePacket = navStatus.packetStatus; |
540 | ignorePacket = navStatus.packetStatus; |
465 | break; |
541 | break; |
466 | /* |
542 | /* |
467 | case MSGID_POSLLH: |
543 | case MSGID_POSLLH: |
468 | ubxP = (char*)&navPosLlh; |
544 | ubxP = (char*)&navPosLlh; |
469 | ubxEp = (char*)(&navPosLlh + sizeof(NAV_POSLLH_t)); |
545 | ubxEp = (char*)(&navPosLlh + sizeof(NAV_POSLLH_t)); |
470 | ubxSp = (char*)&navPosLlh.packetStatus; |
546 | ubxSp = (char*)&navPosLlh.packetStatus; |
471 | ignorePacket = navPosLlh.packetStatus; |
547 | ignorePacket = navPosLlh.packetStatus; |
472 | break; |
548 | break; |
473 | */ |
549 | */ |
474 | case MSGID_POSUTM: |
550 | case MSGID_POSUTM: |
475 | ubxP = (char*)&navPosUtm; |
551 | ubxP = (char*)&navPosUtm; |
476 | ubxEp = (char*)(&navPosUtm + sizeof(NAV_POSUTM_t)); |
552 | ubxEp = (char*)(&navPosUtm + sizeof(NAV_POSUTM_t)); |
477 | ubxSp = (char*)&navPosUtm.packetStatus; |
553 | ubxSp = (char*)&navPosUtm.packetStatus; |
478 | ignorePacket = navPosUtm.packetStatus; |
554 | ignorePacket = navPosUtm.packetStatus; |
479 | break; |
555 | break; |
480 | case MSGID_VELNED: |
556 | case MSGID_VELNED: |
481 | ubxP = (char*)&navVelNed; |
557 | ubxP = (char*)&navVelNed; |
482 | ubxEp = (char*)(&navVelNed + sizeof(NAV_VELNED_t)); |
558 | ubxEp = (char*)(&navVelNed + sizeof(NAV_VELNED_t)); |
483 | ubxSp = (char*)&navVelNed.packetStatus; |
559 | ubxSp = (char*)&navVelNed.packetStatus; |
484 | ignorePacket = navVelNed.packetStatus; |
560 | ignorePacket = navVelNed.packetStatus; |
485 | break; |
561 | break; |
486 | default: |
562 | default: |
487 | ignorePacket = 1; |
563 | ignorePacket = 1; |
488 | ubxSp = (char*)0; |
564 | ubxSp = (char*)0; |
489 | } |
565 | } |
490 | break; |
566 | break; |
491 | case GPS_LEN1: // first len byte |
567 | case GPS_LEN1:// first len byte |
492 | msgLen = c; |
568 | msgLen = c; |
493 | CK_A += c; |
569 | CK_A += c; |
494 | CK_B += CK_A; |
570 | CK_B += CK_A; |
495 | gpsState = GPS_LEN2; |
571 | gpsState = GPS_LEN2; |
496 | break; |
572 | break; |
497 | case GPS_LEN2: // second len byte |
573 | case GPS_LEN2:// second len byte |
498 | msgLen = msgLen + (c * 256); |
574 | msgLen = msgLen + (c * 256); |
499 | CK_A += c; |
575 | CK_A += c; |
500 | CK_B += CK_A; |
576 | CK_B += CK_A; |
501 | gpsState = GPS_FILLING; // next data will be stored in packet struct |
577 | gpsState = GPS_FILLING;// next data will be stored in packet struct |
502 | break; |
578 | break; |
503 | case GPS_FILLING: |
579 | case GPS_FILLING: |
504 | CK_A += c; |
580 | CK_A += c; |
505 | CK_B += CK_A; |
581 | CK_B += CK_A; |
506 | 582 | ||
507 | if ( !ignorePacket && ubxP < ubxEp) |
583 | if ( !ignorePacket && ubxP < ubxEp) |
508 | { |
584 | { |
509 | *ubxP++ = c; |
585 | *ubxP++ = c; |
510 | } |
586 | } |
511 | 587 | ||
512 | if (--msgLen == 0) |
588 | if (--msgLen == 0) |
513 | { |
589 | { |
514 | gpsState = GPS_CKA; |
590 | gpsState = GPS_CKA; |
515 | } |
591 | } |
516 | break; |
592 | break; |
517 | case GPS_CKA: |
593 | case GPS_CKA: |
518 | if (c == CK_A) |
594 | if (c == CK_A) |
519 | { |
595 | { |
520 | gpsState = GPS_CKB; |
596 | gpsState = GPS_CKB; |
521 | } |
597 | } |
522 | else |
598 | else |
523 | { |
599 | { |
524 | gpsState = GPS_EMPTY; |
600 | gpsState = GPS_EMPTY; |
525 | } |
601 | } |
526 | break; |
602 | break; |
527 | case GPS_CKB: |
603 | case GPS_CKB: |
528 | if (c == CK_B && ubxSp) // No error -> packet received successfully |
604 | if (c == CK_B && ubxSp)// No error -> packet received successfully |
529 | { |
605 | { |
530 | *ubxSp = 1; // set packetStatus in struct |
606 | *ubxSp = 1;// set packetStatus in struct |
531 | GPSscanData(); |
607 | GPSscanData(); |
532 | } |
608 | } |
533 | gpsState = GPS_EMPTY; // ready for next packet |
609 | gpsState = GPS_EMPTY;// ready for next packet |
534 | break; |
610 | break; |
535 | default: |
611 | default: |
536 | gpsState = GPS_EMPTY; // ready for next packet |
612 | gpsState = GPS_EMPTY;// ready for next packet |
537 | } |
613 | } |
538 | } |
614 | } |
539 | else // discard any data if error occured |
615 | else// discard any data if error occured |
540 | { |
616 | { |
541 | gpsState = GPS_EMPTY; |
617 | gpsState = GPS_EMPTY; |
542 | } |
618 | } |
543 | } |
619 | } |
544 | 620 | ||
545 | 621 | ||
546 | 622 | ||
547 | 623 | ||
548 | 624 |