Subversion Repositories FlightCtrl

Rev

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