Subversion Repositories FlightCtrl

Rev

Rev 806 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 806 Rev 812
Line 12... Line 12...
12
#define TSK_HOLD                1
12
#define TSK_HOLD                1
13
#define TSK_HOME                2
13
#define TSK_HOME                2
Line 14... Line 14...
14
 
14
 
15
#define GPS_STICK_SENSE         20              // must be at least in a range where 90% of the trimming does not switch of the GPS function
15
#define GPS_STICK_SENSE         20              // must be at least in a range where 90% of the trimming does not switch of the GPS function
16
#define GPS_STICK_LIMIT         45              // limit of gps stick control to avoid critical flight attitudes
-
 
17
#define GPS_D_LIMIT_DIST        500             // for position deviations greater than 500cm the D-Part of the PD-Controller is limited
16
#define GPS_STICK_LIMIT         45              // limit of gps stick control to avoid critical flight attitudes
Line 18... Line -...
18
#define GPS_D_LIMIT                     50              // PD-Controntroller D-Limit.
-
 
19
 
-
 
Line -... Line 17...
-
 
17
#define GPS_POSDEV_INTEGRAL_LIMIT  32000  // limit for the position error integral
20
int16_t GPS_Pitch = 0;
18
 
Line 21... Line 19...
21
int16_t GPS_Roll = 0;
19
 
22
 
20
int16_t GPS_Pitch = 0, GPS_Roll = 0;
Line 94... Line 92...
94
}
92
}
Line 95... Line 93...
95
 
93
 
96
// calculates the GPS control stick values from the deviation to target position
94
// calculates the GPS control stick values from the deviation to target position
97
// if the pointer to the target positin is NULL or is the target position invalid
95
// if the pointer to the target positin is NULL or is the target position invalid
98
// then the P part of the controller is deactivated.
96
// then the P part of the controller is deactivated.
99
void GPS_PDController(GPS_Pos_t *pTargetPos)
97
void GPS_PIDController(GPS_Pos_t *pTargetPos)
100
{
98
{
101
        int32_t coscompass, sincompass;
99
        int32_t coscompass, sincompass;
102
        int32_t GPSPosDev_North, GPSPosDev_East; // Position deviation in cm
100
        int32_t GPSPosDev_North, GPSPosDev_East; // Position deviation in cm
103
        int32_t P_North = 0, D_North = 0, P_East = 0, D_East = 0;
101
        int32_t P_North = 0, D_North = 0, P_East = 0, D_East = 0, I_North = 0, I_East = 0;
-
 
102
        int32_t PID_North = 0, PID_East = 0;
104
        int32_t PD_North = 0, PD_East = 0;
103
        uint8_t GPS_Stick_Limited = 0;
-
 
104
        static int32_t cos_target_latitude = 1;
-
 
105
        static int32_t GPSPosDevIntegral_North = 0, GPSPosDevIntegral_East = 0;
Line 105... Line 106...
105
        static int32_t cos_target_latitude = 1;
106
        static GPS_Pos_t *pLastTargetPos = 0;
106
 
107
 
107
        // if GPS data and Compass are ok
108
        // if GPS data and Compass are ok
Line 108... Line 109...
108
        if((GPSInfo.status == VALID) && (GPSInfo.satfix == SATFIX_3D) && (CompassHeading >= 0) )
109
        if((GPSInfo.status == VALID) && (GPSInfo.satfix == SATFIX_3D) && (CompassHeading >= 0) )
109
        {
110
        {
110
 
111
 
111
                if(pTargetPos != NULL) // if there is a target position
-
 
112
                {
-
 
113
                        if(pTargetPos->Status != INVALID) // and the position data are valid
-
 
-
 
112
                if(pTargetPos != NULL) // if there is a target position
114
                        { // calculate position deviation from latitude and longitude differences
113
                {
115
                                GPSPosDev_North = (GPSInfo.latitude - pTargetPos->Latitude); // to calculate real cm we would need *111/100 additionally
-
 
116
                                GPSPosDev_East  = (GPSInfo.longitude - pTargetPos->Longitude); // to calculate real cm we would need *111/100 additionally
114
                        if(pTargetPos->Status != INVALID) // and the position data are valid
117
                                // recalculate the target latitude projection only if the target data are updated
115
                        {
-
 
116
                                // if the target data are updated or the target pointer has changed
-
 
117
                                if ((pTargetPos->Status != PROCESSED) || (pTargetPos != pLastTargetPos) )
-
 
118
                                {
-
 
119
                                        // reset error integral
118
                                // to save time
120
                                        GPSPosDevIntegral_North = 0;
-
 
121
                                        GPSPosDevIntegral_East = 0;
-
 
122
                                        // recalculate latitude projection
-
 
123
                                        cos_target_latitude = (int32_t)c_cos_8192((int16_t)(pTargetPos->Latitude/10000000L));
119
                                if (pTargetPos->Status != PROCESSED)
124
                                        // remember last target pointer
120
                                {
125
                                        pLastTargetPos = pTargetPos;
-
 
126
                                        // mark data as processed
-
 
127
                                        pTargetPos->Status = PROCESSED;
-
 
128
                                }
121
                                        cos_target_latitude = (int32_t)c_cos_8192((int16_t)(pTargetPos->Latitude/10000000L));
129
                                // calculate position deviation from latitude and longitude differences
122
                                        pTargetPos->Status = PROCESSED;
130
                                GPSPosDev_North = (GPSInfo.latitude - pTargetPos->Latitude); // to calculate real cm we would need *111/100 additionally
123
                                }
131
                                GPSPosDev_East  = (GPSInfo.longitude - pTargetPos->Longitude); // to calculate real cm we would need *111/100 additionally
Line 124... Line 132...
124
                                // calculate latitude projection
132
                                // calculate latitude projection
125
                                GPSPosDev_East  *= cos_target_latitude;
133
                                GPSPosDev_East  *= cos_target_latitude;
126
                                GPSPosDev_East /= 8192;
134
                                GPSPosDev_East /= 8192;
127
 
135
 
128
                                DebugOut.Analog[12] = GPSPosDev_North;
-
 
129
                                DebugOut.Analog[13] = GPSPosDev_East;
-
 
130
                                //DebugOut.Analog[12] = GPSInfo.velnorth;
-
 
131
                                //DebugOut.Analog[13] = GPSInfo.veleast;
-
 
132
 
136
                        DebugOut.Analog[12] = GPSPosDev_North;
133
                                //Calculate P-components of the controller (negative sign for compensation)
137
                                DebugOut.Analog[13] = GPSPosDev_East;
134
                                P_North = -(GPS_P_Factor * GPSPosDev_North)/2048;
138
                                //DebugOut.Analog[12] = GPSInfo.velnorth;
-
 
139
                                //DebugOut.Analog[13] = GPSInfo.veleast;
135
                                P_East =  -(GPS_P_Factor * GPSPosDev_East)/2048;
140
                        }
136
                        }
141
                        else // no valid target position available
-
 
142
                        {
-
 
143
                                // reset error
-
 
144
                                GPSPosDev_North = 0;
137
                        else // not valid target position available
145
                                GPSPosDev_East = 0;
138
                        {
146
                                // reset error integral
139
                                GPSPosDev_North = 0;
147
                                GPSPosDevIntegral_North = 0;
140
                                GPSPosDev_East = 0;
148
                                GPSPosDevIntegral_East = 0;
-
 
149
                        }
141
                        }
150
                }
142
                }
151
                else // no target position available
-
 
152
                {
-
 
153
                        // reset error
-
 
154
                        GPSPosDev_North = 0;
143
                else // not target position available
155
                        GPSPosDev_East = 0;
Line 144... Line 156...
144
                {
156
                        // reset error integral
145
                        GPSPosDev_North = 0;
157
                        GPSPosDevIntegral_North = 0;
146
                        GPSPosDev_East = 0;
158
                        GPSPosDevIntegral_East = 0;
-
 
159
                }
-
 
160
 
147
                }
161
                //Calculate PID-components of the controller (negative sign for compensation)
148
 
162
                P_North = -(GPS_P_Factor * GPSPosDev_North)/2048;
149
                //Calculate PD-components of the controller (negative sign for compensation)
-
 
150
                P_North = -(GPS_P_Factor * GPSPosDev_North)/2048;
-
 
151
                P_East =  -(GPS_P_Factor * GPSPosDev_East)/2048;
-
 
152
                D_North = -(GPS_D_Factor * GPSInfo.velnorth)/512;
-
 
153
                D_East =  -(GPS_D_Factor * GPSInfo.veleast)/512;
-
 
154
                // limit D-Part if position deviation is significant of the target position
-
 
155
                // this accelerates flying to the target position
-
 
156
                if( (abs(GPSPosDev_North) > GPS_D_LIMIT_DIST) ||  (abs(GPSPosDev_East) > GPS_D_LIMIT_DIST) )
-
 
157
                {
-
 
158
                        if (D_North > GPS_D_LIMIT) D_North = GPS_D_LIMIT;
163
                P_East =  -(GPS_P_Factor * GPSPosDev_East)/2048;
159
                        else if (D_North < -GPS_D_LIMIT) D_North = -GPS_D_LIMIT;
164
                I_North = -(GPS_I_Factor * GPSPosDevIntegral_North)/2048;
160
                        if (D_East > GPS_D_LIMIT)  D_East  = GPS_D_LIMIT;
165
                I_East =  -(GPS_I_Factor * GPSPosDevIntegral_East)/2048;
Line 161... Line 166...
161
                        else if (D_East  < -GPS_D_LIMIT) D_East  = -GPS_D_LIMIT;
166
                D_North = -(GPS_D_Factor * GPSInfo.velnorth)/512;
Line 162... Line 167...
162
                }
167
                D_East =  -(GPS_D_Factor * GPSInfo.veleast)/512;
163
                // PD-controller
168
                // PD-controller
Line 178... Line 183...
178
                // in the fc.c. Therefore a positive north deviation/velocity should result in a positive
183
                // in the fc.c. Therefore a positive north deviation/velocity should result in a positive
179
                // GPS_Pitch and a positive east deviation/velocity should result in a negative GPS_Roll.
184
                // GPS_Pitch and a positive east deviation/velocity should result in a negative GPS_Roll.
Line 180... Line 185...
180
 
185
 
181
                coscompass = (int32_t)c_cos_8192(CompassHeading);
186
                coscompass = (int32_t)c_cos_8192(CompassHeading);
182
                sincompass = (int32_t)c_sin_8192(CompassHeading);
187
                sincompass = (int32_t)c_sin_8192(CompassHeading);
183
                GPS_Roll  =    (int16_t)((coscompass * PD_East - sincompass * PD_North) / 8192);
188
                GPS_Roll  =    (int16_t)((coscompass * PID_East - sincompass * PID_North) / 8192);
Line 184... Line 189...
184
                GPS_Pitch = -1*(int16_t)((sincompass * PD_East + coscompass * PD_North) / 8192);
189
                GPS_Pitch = -1*(int16_t)((sincompass * PID_East + coscompass * PID_North) / 8192);
185
 
190
 
-
 
191
                // limit GPS controls
-
 
192
                if (GPS_Pitch > GPS_STICK_LIMIT)
-
 
193
                {
-
 
194
                        GPS_Pitch =  GPS_STICK_LIMIT;
186
                // limit GPS controls
195
                        GPS_Stick_Limited = 1;
-
 
196
                }
-
 
197
                else if (GPS_Pitch < -GPS_STICK_LIMIT)
-
 
198
                {
-
 
199
                        GPS_Pitch = -GPS_STICK_LIMIT;
187
                if (GPS_Pitch >  GPS_STICK_LIMIT) GPS_Pitch =  GPS_STICK_LIMIT;
200
                        GPS_Stick_Limited = 1;
-
 
201
                }
-
 
202
                if (GPS_Roll > GPS_STICK_LIMIT)
-
 
203
                {
-
 
204
                        GPS_Roll = GPS_STICK_LIMIT;
188
                else if (GPS_Pitch < -GPS_STICK_LIMIT) GPS_Pitch = -GPS_STICK_LIMIT;
205
                        GPS_Stick_Limited = 1;
-
 
206
                }
-
 
207
                else if (GPS_Roll < -GPS_STICK_LIMIT)
-
 
208
                {
-
 
209
                        GPS_Roll = -GPS_STICK_LIMIT;
-
 
210
                        GPS_Stick_Limited = 1;
-
 
211
                }
-
 
212
 
-
 
213
                if(!GPS_Stick_Limited) // prevent further growing if error integrals if control limit is reached
-
 
214
                {
-
 
215
                        // calculate position error integrals
-
 
216
                        GPSPosDevIntegral_North += GPSPosDev_North/4;
-
 
217
                        if( GPSPosDevIntegral_North > GPS_POSDEV_INTEGRAL_LIMIT) GPSPosDevIntegral_North = GPS_POSDEV_INTEGRAL_LIMIT;
-
 
218
                        else if (GPSPosDevIntegral_North < -GPS_POSDEV_INTEGRAL_LIMIT) GPSPosDevIntegral_North = -GPS_POSDEV_INTEGRAL_LIMIT;
-
 
219
                        GPSPosDevIntegral_East += GPSPosDev_East/4;
-
 
220
                        if( GPSPosDevIntegral_East > GPS_POSDEV_INTEGRAL_LIMIT) GPSPosDevIntegral_East = GPS_POSDEV_INTEGRAL_LIMIT;
-
 
221
                        else if (GPSPosDevIntegral_East < -GPS_POSDEV_INTEGRAL_LIMIT) GPSPosDevIntegral_East = -GPS_POSDEV_INTEGRAL_LIMIT;
189
                if (GPS_Roll  >  GPS_STICK_LIMIT)  GPS_Roll =  GPS_STICK_LIMIT;
222
                }
190
                else if (GPS_Roll  < -GPS_STICK_LIMIT)  GPS_Roll = -GPS_STICK_LIMIT;
223
 
191
        }
224
        }
192
        else // invalid GPS data
225
        else // invalid GPS data
-
 
226
        {
-
 
227
                GPS_Neutral(); // do nothing
-
 
228
                // reset error integral
193
        {
229
                GPSPosDevIntegral_North = 0;
194
                GPS_Neutral(); // do nothing
230
                GPSPosDevIntegral_East = 0;
Line -... Line 231...
-
 
231
        }
-
 
232
}
195
        }
233
 
196
}
234
 
197
 
235
 
198
 
236
 
199
void GPS_Main(uint8_t ctrl)
237
void GPS_Main(uint8_t ctrl)
Line 255... Line 293...
255
                                                {
293
                                                {
256
                                                        if(GPS_P_Delay<7)
294
                                                        if(GPS_P_Delay<7)
257
                                                        { // delayed activation of P-Part for 8 cycles (8*0.25s = 2s)
295
                                                        { // delayed activation of P-Part for 8 cycles (8*0.25s = 2s)
258
                                                                GPS_P_Delay++;
296
                                                                GPS_P_Delay++;
259
                                                                GPS_SetHoldPosition();  // update hold point to current gps position
297
                                                                GPS_SetHoldPosition();  // update hold point to current gps position
260
                                                                GPS_PDController(NULL); // activates only the D-Part
298
                                                                GPS_PIDController(NULL); // activates only the D-Part
261
                                                        }
299
                                                        }
262
                                                        else GPS_PDController(&HoldPosition);// activates the P&D-Part
300
                                                        else GPS_PIDController(&HoldPosition);// activates the P&D-Part
263
                                                }
301
                                                }
264
                                        }
302
                                        }
265
                                        else // invalid Hold Position
303
                                        else // invalid Hold Position
266
                                        {  // try to catch a valid hold position from gps data input
304
                                        {  // try to catch a valid hold position from gps data input
267
                                                GPS_SetHoldPosition();
305
                                                GPS_SetHoldPosition();
Line 278... Line 316...
278
                                                {
316
                                                {
279
                                                        GPS_Neutral();
317
                                                        GPS_Neutral();
280
                                                }
318
                                                }
281
                                                else // GPS control active
319
                                                else // GPS control active
282
                                                {
320
                                                {
283
                                                        GPS_PDController(&HomePosition);
321
                                                        GPS_PIDController(&HomePosition);
284
                                                }
322
                                                }
285
                                        }
323
                                        }
286
                                        else // bad home position
324
                                        else // bad home position
287
                                        {
325
                                        {
288
                                                BeepTime = 50; // signal invalid home position
326
                                                BeepTime = 50; // signal invalid home position
Line 294... Line 332...
294
                                                        {
332
                                                        {
295
                                                                GPS_Neutral();
333
                                                                GPS_Neutral();
296
                                                        }
334
                                                        }
297
                                                        else // GPS control active
335
                                                        else // GPS control active
298
                                                        {
336
                                                        {
299
                                                                GPS_PDController(&HoldPosition);
337
                                                                GPS_PIDController(&HoldPosition);
300
                                                        }
338
                                                        }
301
                                                }
339
                                                }
302
                                                else
340
                                                else
303
                                                { // try to catch a valid hold position
341
                                                { // try to catch a valid hold position
304
                                                        GPS_SetHoldPosition();
342
                                                        GPS_SetHoldPosition();