Subversion Repositories FlightCtrl

Rev

Rev 987 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
966 MikeW 1
/*
2
Copyright 2008, by Michael Walter
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
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.
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/>.
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
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.
13
*/
14
 
15
 
16
/*****************************************************************************
17
  INCLUDES
18
**************************************************************************** */
19
#include "kafi.h"
20
#include "FlightControl.h"
21
#include "main.h"
22
#include "mm3.h"
23
#include "main.h"
24
#include "eeprom.c"
25
 
26
/*****************************************************************************
27
(SYMBOLIC) CONSTANTS
28
*****************************************************************************/
29
#define MAX_GAS 250
30
#define MIN_GAS    15
31
 
32
#define sin45 sin(45.F / 180.F * PI) 
33
#define cos45 cos(45.F / 180.F * PI)
34
 
35
/*****************************************************************************
36
  VARIABLES
37
*****************************************************************************/
38
 
39
extern void GPSupdate(void);
40
 
973 MikeW 41
f32_t AdNeutralNick = 0.0F, AdNeutralRoll = 0.0F, AdNeutralGier = 0.0F;
966 MikeW 42
int NeutralAccX = 0, NeutralAccY = 0, NeutralAccZ = 0;
973 MikeW 43
int AverageRoll = 0, AverageNick = 0, AverageGier = 0;
966 MikeW 44
int AveragerACC_X = 0, AveragerACC_Y = 0, AveragerACC_Z = 0;
45
 
46
f32_t Roll_X_Offset = 0.F, Roll_Y_Offset = 0.F, Roll_Z_Offset = 0.F;
47
f32_t ACC_X_Offset = 0.F, ACC_Y_Offset = 0.F,  ACC_Z_Offset = 0.F;
48
 
49
int DeltaAltitude = 0, CurrentAltitude = 0, LastAltitude = 0, InitialAltitude = 0;
50
int SummeNick=0,SummeRoll=0, StickNick = 0,StickRoll = 0,StickGier = 0, sollGier = 0;
51
int GierMischanteil, GasMischanteil;
52
 
53
unsigned char Motor_Vorne,Motor_Hinten,Motor_Rechts,Motor_Links, Count;
54
unsigned char MotorWert[5];
55
unsigned char SenderOkay = 0;
56
unsigned int I2CTimeout = 100;
57
char MotorenEin = 0;
983 MikeW 58
unsigned int  modell_fliegt = 0;
966 MikeW 59
 
60
extern unsigned long maxDistance;
61
extern signed int GPS_Nick,  GPS_Roll;
62
extern int RemoteLinkLost;
987 mikew 63
extern int InvalidAttitude;
966 MikeW 64
struct mk_param_struct EE_Parameter;
65
 
66
/* ****************************************************************************
67
Functionname:     SetNeutral                      */ /*!
68
Description:    
69
 
70
@param[in]        
71
 
72
  @return           void
73
  @pre              -
74
  @post             -
75
  @author         Michael Walter  
76
**************************************************************************** */
77
void SetNeutral(void)
78
{
983 MikeW 79
  beeptime = 2000;
966 MikeW 80
  Delay_ms(1000);
81
  if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG))  // Höhenregelung aktiviert?
82
  {    
83
    if((AdWertAirPressure_Raw > 950) || (AdWertAirPressure_Raw < 750))
84
    {
85
      SucheLuftruckOffset();
86
    }
87
  }
88
 
89
  LastAltitude = CurrentAltitude;
90
  Delay_ms_Mess(300);
91
 
92
  ANALOG_OFF;
973 MikeW 93
  AdNeutralNick = (f32_t) AdWertNick_Raw;
94
  AdNeutralRoll = (f32_t) AdWertRoll_Raw;
95
  AdNeutralGier = (f32_t) AdWertGier_Raw;
966 MikeW 96
  NeutralAccY = AdWertAccRoll_Raw;
97
  NeutralAccX = AdWertAccNick_Raw;
98
  NeutralAccZ = AdWertAccHoch_Raw;
99
 
100
  Roll_X_Offset = 0.F;
101
  Roll_Y_Offset = 0.F;
102
  Roll_Z_Offset = 0.F;
103
  ACC_X_Offset = 0.F;
104
  ACC_Y_Offset = 0.F;
105
  ACC_Z_Offset = 0.F;
106
 
107
  AccumulatedACC_X = 0;
108
  AccumulatedACC_X_cnt = 0;
109
  AccumulatedACC_Y = 0;
110
  AccumulatedACC_Y_cnt = 0;
111
  AccumulatedACC_Z = 0;
112
  AccumulatedACC_Z_cnt = 0;
113
 
973 MikeW 114
  AccumulatedRoll = 0;
115
  AccumulatedRoll_cnt = 0;
116
  AccumulatedNick = 0;
117
  AccumulatedNick_cnt = 0;
118
  AccumulatedGier = 0;
119
  AccumulatedGier_cnt = 0;
966 MikeW 120
 
121
  AveragerACC_X = 0;
122
  AveragerACC_Y = 0;
123
  AveragerACC_Z = 0;
124
 
125
  AccumulatedACC_X = 0;
126
  AccumulatedACC_X_cnt = 0;
127
  AccumulatedACC_Y = 0;
128
  AccumulatedACC_Y_cnt = 0;
129
  AccumulatedACC_Z = 0;
130
  AccumulatedACC_Z_cnt = 0;
131
  ANALOG_ON;
132
 
133
  SummeRoll = 0;
134
  SummeNick = 0;
135
 
136
  sollGier = status.iPsi10;
137
  InitialAltitude = AdWertAirPressure_Raw;
987 mikew 138
 
139
  InvalidAttitude = 0;
966 MikeW 140
  beeptime = 2000;
141
}
142
 
143
 
144
/* ****************************************************************************
145
Functionname:    GetMeasurements                      */ /*!
146
Description:    CalculateAverage
147
 
148
@param[in]        
149
 
150
  @return           void
151
  @pre              -
152
  @post             -
153
  @author         Michael Walter  
154
**************************************************************************** */
155
void GetMeasurements(void)
1040 MikeW 156
{
157
  static int LongTermAccumulatedRoll = 0;
158
  static int LongTermAccumulatedNick = 0;
159
  static int LongTermAccumulatedRoll_Cnt = 0;
160
  static int LongTermAccumulatedNick_Cnt = 0;
161
 
966 MikeW 162
  ANALOG_OFF;
973 MikeW 163
  AverageRoll = AccumulatedRoll / AccumulatedRoll_cnt;
164
  AverageNick = AccumulatedNick / AccumulatedNick_cnt;
165
  AverageGier = AccumulatedGier / AccumulatedGier_cnt;
966 MikeW 166
 
167
  /* Get Pressure Differenz */
168
  CurrentAltitude = InitialAltitude - AccumulatedAirPressure / AccumulatedAirPressure_cnt;
169
  AccumulatedAirPressure_cnt = 0;
170
  AccumulatedAirPressure = 0;
171
 
172
  static char AirPressureCnt = 0;
173
  if (AirPressureCnt % 25 == 1)
174
  {
175
    DeltaAltitude = CurrentAltitude - LastAltitude;
176
    LastAltitude = CurrentAltitude;
177
  }
178
  AirPressureCnt++;
983 MikeW 179
 
1040 MikeW 180
  if (LongTermAccumulatedRoll_Cnt < 500)
966 MikeW 181
  {
1040 MikeW 182
    if (abs(LongTermAccumulatedRoll) < 10000)
183
    {
184
        LongTermAccumulatedRoll += AverageRoll;
185
    }
186
    LongTermAccumulatedRoll_Cnt++;
187
 
188
    if(abs(LongTermAccumulatedNick) < 10000)
189
    {
190
        LongTermAccumulatedNick += AverageNick;
191
    }
192
    LongTermAccumulatedNick_Cnt++;
193
  }
194
  else
195
  {
196
   static float fPreviousPsi =0.0F;
197
   static float fPreviousTheta =0.0F;
198
 
199
    //DebugOut.Analog[8] = (int) (((status.Phi - fPreviousPsi) / (0.00001F * fCycleTime)) / LongTermAccumulatedRoll_Cnt );
200
    //DebugOut.Analog[9] = (int) ((LongTermAccumulatedRoll / LongTermAccumulatedRoll_Cnt));
201
 
202
    AdNeutralRoll += (int) ((LongTermAccumulatedRoll + (status.Phi - fPreviousPsi) / (0.00001F * fCycleTime)) / LongTermAccumulatedRoll_Cnt );
203
    AdNeutralNick += (int) ((LongTermAccumulatedNick + (status.Theta - fPreviousTheta) / (0.00001F * fCycleTime)) / LongTermAccumulatedNick_Cnt );
204
 
205
    fPreviousPsi = status.Phi;
206
    fPreviousTheta =  status.Theta;
207
 
208
    //AdNeutralRoll += (MAX(-20, MIN(20,LongTermAccumulatedRoll / LongTermAccumulatedRoll_Cnt)));
209
    //AdNeutralNick += (MAX(-20, MIN(20,LongTermAccumulatedNick / LongTermAccumulatedNick_Cnt)));
210
 
211
    LongTermAccumulatedRoll_Cnt = 0;
212
    LongTermAccumulatedNick_Cnt = 0;
213
    LongTermAccumulatedRoll = 0;
214
    LongTermAccumulatedNick = 0;
215
  }
216
 
217
#if 0
218
  DebugOut.Analog[3] = fSumNick;
219
  DebugOut.Analog[4] = fSumRoll;
220
  DebugOut.Analog[5] = fSumGier;
221
#endif  
222
 
223
 
224
  if((modell_fliegt < 0x250) && 0)
225
  {
983 MikeW 226
    //if ((GPS_Roll == 0 && GPS_Nick == 0) || (maxDistance / 10 > 10))
227
    AdNeutralNick = 0.998F * AdNeutralNick + 0.002F * AdWertNick_Raw;
228
    AdNeutralRoll = 0.998F * AdNeutralRoll + 0.002F * AdWertRoll_Raw;
229
    if (abs(StickGier) < 15 || MotorenEin == 0)
230
    {
231
      AdNeutralGier = 0.998F * AdNeutralGier + 0.002F * AdWertGier_Raw;
232
    }
233
  }
1040 MikeW 234
  else if(modell_fliegt < 0x2000&& 0)
983 MikeW 235
  {
236
    //if ((GPS_Roll == 0 && GPS_Nick == 0) || (maxDistance / 10 > 10))
973 MikeW 237
    AdNeutralNick = 0.999F * AdNeutralNick + 0.001F * AdWertNick_Raw;
238
    AdNeutralRoll = 0.999F * AdNeutralRoll + 0.001F * AdWertRoll_Raw;
966 MikeW 239
    if (abs(StickGier) < 15 || MotorenEin == 0)
240
    {
983 MikeW 241
      AdNeutralGier = 0.999F * AdNeutralGier + 0.001F * AdWertGier_Raw;
966 MikeW 242
    }
243
  }
983 MikeW 244
  else
245
  {
246
    AdNeutralNick = 0.9995F * AdNeutralNick + 0.0005F * AdWertNick_Raw;
247
    AdNeutralRoll = 0.9995F * AdNeutralRoll + 0.0005F * AdWertRoll_Raw;
248
    if (abs(StickGier) < 15 || MotorenEin == 0)
249
    {
250
      AdNeutralGier = 0.9995F * AdNeutralGier + 0.0005F * AdWertGier_Raw;
251
    }
252
  }
966 MikeW 253
 
254
#if 1
973 MikeW 255
  DebugOut.Analog[6] = AdWertNick_Raw;
256
  DebugOut.Analog[7] = AdWertRoll_Raw;
257
  DebugOut.Analog[8] = AdWertGier_Raw;
258
 
259
  DebugOut.Analog[9] = AdNeutralNick;
260
  DebugOut.Analog[10] = AdNeutralRoll;
261
  DebugOut.Analog[11] = AdNeutralGier;
966 MikeW 262
#endif
983 MikeW 263
 
973 MikeW 264
  AccumulatedRoll = 0;
265
  AccumulatedRoll_cnt = 0;
266
  AccumulatedNick = 0;
267
  AccumulatedNick_cnt = 0;
268
  AccumulatedGier = 0;
269
  AccumulatedGier_cnt = 0;
966 MikeW 270
 
271
#if 0
272
  ACC_X_Offset = 0.9999F * ACC_X_Offset + 0.0001F * ((float) AccumulatedACC_X / (float) AccumulatedACC_X_cnt);
273
  ACC_Y_Offset = 0.9999F * ACC_Y_Offset + 0.0001F * ((float) AccumulatedACC_Y / (float) AccumulatedACC_Y_cnt);
274
  ACC_Z_Offset = 0.9999F * ACC_Z_Offset + 0.0001F * ((float) AccumulatedACC_Z / (float) AccumulatedACC_Z_cnt);
275
#endif
276
 
277
  AveragerACC_X =  AccumulatedACC_X / AccumulatedACC_X_cnt;
278
  AveragerACC_Y =  AccumulatedACC_Y / AccumulatedACC_Y_cnt;
279
  AveragerACC_Z =  AccumulatedACC_Z / AccumulatedACC_Z_cnt;
280
 
281
  AccumulatedACC_X = 0;
282
  AccumulatedACC_X_cnt = 0;
283
  AccumulatedACC_Y = 0;
284
  AccumulatedACC_Y_cnt = 0;
285
  AccumulatedACC_Z = 0;
286
  AccumulatedACC_Z_cnt = 0;
287
 
288
  ANALOG_ON;
289
}
290
 
291
/* ****************************************************************************
292
Functionname:     SendMotorData                      */ /*!
293
Description:          Senden der Motorwerte per I2C-Bus
294
 
295
  @return           void
296
  @pre              -
297
  @post             -
298
  @author           H. Buss / I. Busker
299
**************************************************************************** */
300
void SendMotorData(void)
301
{
302
  if(!MotorenEin)
303
  {
304
    Motor_Hinten = 0;
305
    Motor_Vorne = 0;
306
    Motor_Rechts = 0;
307
    Motor_Links = 0;
308
    if(MotorTest[0]) Motor_Vorne = MotorTest[0];
309
    if(MotorTest[1]) Motor_Hinten = MotorTest[1];
310
    if(MotorTest[2]) Motor_Links = MotorTest[2];
311
    if(MotorTest[3]) Motor_Rechts = MotorTest[3];
312
  }
313
 
314
  //Start I2C Interrupt Mode
315
  twi_state = 0;
316
  motor = 0;
317
  i2c_start();
318
}
319
 
320
 
321
/* ****************************************************************************
322
Functionname:     RemoteControl                      */ /*!
323
Description:      
324
 
325
  @return           void
326
  @pre              -
327
  @post             -
328
  @author           H. Buss / I. Busker
329
**************************************************************************** */
330
void RemoteControl(void)
331
{
332
  static unsigned char delay_neutral = 0;
333
  static unsigned char delay_einschalten = 0,delay_ausschalten = 0;
334
 
335
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
336
  // Gaswert ermitteln
337
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
338
  GasMischanteil = PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] + 120;
339
  if(GasMischanteil < 0)
340
  {
341
    GasMischanteil = 0;
342
  }
343
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
344
  // Emfang schlecht
345
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
346
  if(SenderOkay < 100)
347
  {
348
    if(!PcZugriff)
349
    {
350
      if(BeepMuster == 0xffff)
351
      {
352
        beeptime = 15000;
353
        BeepMuster = 0x0c00;
354
      }
355
    }
356
  }
357
  else
358
  {
359
    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360
    // Emfang gut
361
    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
362
    if(SenderOkay > 140)
363
    {
364
      if(GasMischanteil > 40)
365
      {
366
        if(modell_fliegt < 0xffff)
367
        {
368
          modell_fliegt++;
369
        }
370
      }
371
 
372
 
373
      if((GasMischanteil > 200) &&
374
        (MotorenEin == 0))
375
      {
376
        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
377
        // auf Nullwerte kalibrieren
378
        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
379
        if(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] > 75)  // Neutralwerte
380
        {
381
          if(++delay_neutral > 50)  // nicht sofort
382
          {
383
            MotorenEin = 0;
384
            delay_neutral = 0;
385
            modell_fliegt = 0;
386
            if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG))  // Höhenregelung aktiviert?
387
            {
388
              if((AdWertAirPressure_Raw > 950) || (AdWertAirPressure_Raw < 750))
389
              {
390
                SucheLuftruckOffset();
391
              }
392
            }  
393
            ReadParameterSet(GetActiveParamSetNumber(), (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
394
            SetNeutral();
395
          }
396
        }
397
        else
398
        {
399
          delay_neutral = 0;
400
        }
401
      }
402
      // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
403
      // Gas ist unten
404
      // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
405
      if(GasMischanteil < 35)
406
      {
407
        // Starten
408
        if(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] < -75)
409
        {
410
          // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
411
          // Einschalten
412
          // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
413
          if(++delay_einschalten > 100)
414
          {
415
            MotorenEin = 1;
416
            modell_fliegt = 1;
417
            delay_einschalten = 100;
418
          }          
419
        }  
420
        else
421
        {
422
          delay_einschalten = 0;
423
        }
424
        //Auf Neutralwerte setzen
425
        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
426
        // Auschalten
427
        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
428
        if(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] > 75)
429
        {
430
          if(++delay_ausschalten > 50)  // nicht sofort
431
          {
432
            MotorenEin = 0;
433
            modell_fliegt = 0;
434
            delay_ausschalten = 50;
435
          }
436
        }
437
        else
438
        {
439
          delay_ausschalten = 0;
440
        }
441
      }
442
    }
443
  }
444
}
445
 
446
 
447
 
448
 
449
/* ****************************************************************************
450
Functionname:     PD_Regler                      */ /*!
451
Description:
452
 
453
  @return           void
454
  @pre              -
455
  @post             -
456
  @author           Michael Walter
457
**************************************************************************** */
458
void PD_Regler(void)
459
{
460
  int StickNick45,StickRoll45;
461
  int DiffNick,DiffRoll, DiffGier;    
462
  int motorwert = 0;
463
  int pd_ergebnis;
464
 
465
  /*****************************************************************************
466
  Update noimial attitude
467
  **************************************************************************** */
468
  if(!NewPpmData--)  
469
  {
470
    StickNick = (StickNick * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] * EE_Parameter.Stick_P) / 4;
471
    StickRoll = (StickRoll * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] * EE_Parameter.Stick_P) / 4;
472
    StickGier = -PPM_in[EE_Parameter.Kanalbelegung[K_GIER]];
473
  } // Ende neue Funken-Werte
474
 
475
#ifdef USE_GPS
476
 /* G P S   U p d a t e */
477
  GPSupdate();
478
#endif
479
 
480
  static float AverageGasMischanteil = 50.F;
481
  if((GasMischanteil > 30) &&
482
    (MotorenEin == 1) &&
483
    (RemoteLinkLost == 0) )
484
  {  /* Average the average throttle to find the hover setting */
485
    AverageGasMischanteil = 0.999F * AverageGasMischanteil + 0.001F * GasMischanteil;
486
  }
487
  /* Overide GasMischanteil */
488
  static unsigned int DescentCnt = 32000;
489
  if ((RemoteLinkLost == 1) &&
490
    (MotorenEin == 1))
491
  {
492
    if ((UBat < 100) || /* Start to descent in case of low loltage or in case*/
493
    (maxDistance / 10 < 12)) /* we reached our target position */
494
    {
495
      if (DescentCnt > 0)
496
      {
497
        DescentCnt--;
498
      }
499
      else
500
      {  /* We reached our target (hopefully) */
501
        MotorenEin = 0;
502
        RemoteLinkLost = 0;
503
      }
504
    }
505
    else
506
    {
507
      DescentCnt = 32000;
508
    }
509
    /* Bias the throttle for a slow descent */
510
    GasMischanteil = (int) ((AverageGasMischanteil + 5.0F) * (DescentCnt / 32000.F));
511
  }
512
  else
513
  {
514
    DescentCnt = 32000;
515
  }
516
 
517
  //DebugOut.Analog[13] = (int) GasMischanteil;
518
 
972 MikeW 519
#ifdef X_FORMATION
966 MikeW 520
  /* Overide in case the remote link got lost */
521
  if (RemoteLinkLost == 0)
522
  { /* We are flying in X-Formation */
523
    StickRoll45 = (int) (0.707F *  (float)(StickRoll - GPS_Roll) - 0.707F * (float)(StickNick - GPS_Nick));
524
    StickNick45 = (int) (0.707F *  (float)(StickRoll - GPS_Roll) + 0.707F * (float)(StickNick - GPS_Nick));
525
  }
526
  else
527
  {  /* GPS overide is aktive */
528
    StickRoll45 = (int) (0.707F *  (float)(-GPS_Roll) - 0.707F * (float)(-GPS_Nick));
529
    StickNick45 = (int) (0.707F *  (float)(-GPS_Roll) + 0.707F * (float)(-GPS_Nick));
530
    StickGier = 0;
531
  }
972 MikeW 532
#else
533
  /* Overide in case the remote link got lost */
534
  if (RemoteLinkLost == 0)
535
  { /* We are flying in X-Formation */
536
    StickRoll45 = StickRoll - GPS_Roll;
537
    StickNick45 = StickNick - GPS_Nick;
538
  }
539
  else
540
  {  /* GPS overide is aktive */
541
    StickRoll45 = -GPS_Roll;
542
    StickNick45 = -GPS_Nick;
543
    StickGier = 0;
544
  }
545
#endif
546
 
966 MikeW 547
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
548
  //  Yaw
549
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
550
 
551
  if(GasMischanteil < 20)
552
  {
553
    sollGier = status.iPsi10;
554
    SummeRoll = 0;
555
    SummeNick = 0;
556
  }
557
 
558
  /* Gier-Anteil */
559
  if (abs(StickGier) > 4)
560
  {
561
    sollGier = status.iPsi10 + 4 * StickGier;  
562
  }
563
  DiffGier = (sollGier - status.iPsi10);
973 MikeW 564
  GierMischanteil = (int) (-4 *  DiffGier - 4* (AdWertGier_Raw - (int) AdNeutralGier)) / 10;
966 MikeW 565
 
566
#define MUL_G  0.8
567
  if(GierMischanteil > MUL_G * GasMischanteil)
568
  {
569
    GierMischanteil = MUL_G * GasMischanteil;
570
  }
571
  if(GierMischanteil < -MUL_G * GasMischanteil)
572
  {
573
    GierMischanteil = -MUL_G * GasMischanteil;
574
  }
575
  if(GierMischanteil > 50)
576
  {
577
    GierMischanteil = 50;
578
  }
579
  if(GierMischanteil < -50)
580
  {
581
    GierMischanteil = -50;
582
  }
583
 
584
  /*****************************************************************************
585
  PD-Control
586
  **************************************************************************** */
587
  int scale_p;
588
  int scale_d;
589
 
590
  scale_p = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 170)) / 20);
591
  scale_d = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 170)) / 20);  
592
 
593
  scale_p = 6;
594
  scale_d = 7;
595
 
596
  //DebugOut.Analog[14] =  scale_p;
597
  //DebugOut.Analog[15] =  scale_d;
598
 
599
  /* Pitch */
600
  DiffNick = -(status.iTheta10 + StickNick45);
601
  /* R o l l */
602
  DiffRoll = -(status.iPhi10 + StickRoll45);
603
 
604
  SummeNick += DiffNick;
605
  if(SummeNick >  10000)
606
  {
607
    SummeNick =  10000;
608
  }
609
  if(SummeNick < -10000)
610
  {
611
    SummeNick = -10000;
612
  }
613
 
614
  SummeRoll += DiffRoll;  
615
  if(SummeRoll >  10000)
616
  {
617
    SummeRoll =  10000;
618
  }
619
  if(SummeRoll < -10000)
620
  {
621
    SummeRoll = -10000;
622
  }
623
 
973 MikeW 624
  pd_ergebnis = ((scale_p *DiffNick + scale_d * (AdWertNick_Raw - (int) AdNeutralNick)) / 10) ; // + (int)(SummeNick / 2000); 
966 MikeW 625
  if(pd_ergebnis >  (GasMischanteil + abs(GierMischanteil)))
626
  {
627
    pd_ergebnis =  (GasMischanteil + abs(GierMischanteil));
628
  }
629
  if(pd_ergebnis < -(GasMischanteil + abs(GierMischanteil)))
630
  {
631
    pd_ergebnis = -(GasMischanteil + abs(GierMischanteil));
632
  }
633
 
634
  /* M o t o r   V o r n */
635
  motorwert = GasMischanteil + pd_ergebnis + GierMischanteil;
636
  if ((motorwert < 0))
637
  {
638
    motorwert = 0;
639
  }
640
  else if(motorwert > MAX_GAS)
641
  {
642
    motorwert = MAX_GAS;
643
  }
644
  if (motorwert < MIN_GAS)
645
  {
646
    motorwert = MIN_GAS;
647
  }
648
  Motor_Vorne = motorwert;  
649
 
650
  /* M o t o r   H e c k */
651
  motorwert = GasMischanteil - pd_ergebnis + GierMischanteil;
652
  if ((motorwert < 0))
653
  {
654
    motorwert = 0;
655
  }
656
  else if(motorwert > MAX_GAS)
657
  {
658
    motorwert = MAX_GAS;
659
  }
660
  if (motorwert < MIN_GAS)
661
  {
662
    motorwert = MIN_GAS;
663
  }
664
  Motor_Hinten = motorwert;
665
 
973 MikeW 666
  pd_ergebnis =  ((scale_p * DiffRoll + scale_d * (AdWertRoll_Raw - (int) AdNeutralRoll)) / 10) ; //+ (int)(SummeRoll / 2000);
966 MikeW 667
  if(pd_ergebnis >  (GasMischanteil + abs(GierMischanteil)))
668
  {
669
    pd_ergebnis =  (GasMischanteil + abs(GierMischanteil));
670
  }
671
  if(pd_ergebnis < -(GasMischanteil + abs(GierMischanteil)))
672
  {
673
    pd_ergebnis = -(GasMischanteil + abs(GierMischanteil));
674
  }
675
 
676
  /* M o t o r   L i n k s */
677
  motorwert = GasMischanteil + pd_ergebnis - GierMischanteil;
678
  if(motorwert > MAX_GAS)
679
  {
680
    motorwert = MAX_GAS;
681
  }
682
  if (motorwert < MIN_GAS)
683
  {
684
    motorwert = MIN_GAS;
685
  }
686
  Motor_Links = motorwert;
687
 
688
  /* M o t o r   R e c h t s */
689
  motorwert = GasMischanteil - pd_ergebnis - GierMischanteil;
690
  if(motorwert > MAX_GAS)
691
  {
692
    motorwert = MAX_GAS;
693
  }
694
  if (motorwert < MIN_GAS)
695
  {
696
    motorwert = MIN_GAS;
697
  }
698
  Motor_Rechts = motorwert;
699
 
700
#if 1
701
  DebugOut.Analog[0] = status.iTheta10;
702
  DebugOut.Analog[1] = status.iPhi10;
703
  DebugOut.Analog[2] = status.iPsi10 / 10;
704
#endif
705
}