Subversion Repositories FlightCtrl

Rev

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
/* ****************************************************************************