Subversion Repositories FlightCtrl

Rev

Rev 966 | Rev 973 | Go to most recent revision | 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
 
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++;
972 MikeW 171
 
966 MikeW 172
  //if ((GPS_Roll == 0 && GPS_Nick == 0) || (maxDistance / 10 > 10))
173
  {
972 MikeW 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)));
966 MikeW 176
 
177
    if (abs(StickGier) < 15 || MotorenEin == 0)
178
    {
972 MikeW 179
      Roll_Z_Offset = 0.9998F * Roll_Z_Offset + 0.0002F * (float) ( MAX(-60, MIN(60,AverageRoll_Z)));
966 MikeW 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
  Update noimial attitude
424
  **************************************************************************** */
425
  if(!NewPpmData--)  
426
  {
427
    StickNick = (StickNick * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] * EE_Parameter.Stick_P) / 4;
428
    StickRoll = (StickRoll * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] * EE_Parameter.Stick_P) / 4;
429
    StickGier = -PPM_in[EE_Parameter.Kanalbelegung[K_GIER]];
430
  } // Ende neue Funken-Werte
431
 
432
#ifdef USE_GPS
433
 /* G P S   U p d a t e */
434
  GPSupdate();
435
#endif
436
 
437
  static float AverageGasMischanteil = 50.F;
438
  if((GasMischanteil > 30) &&
439
    (MotorenEin == 1) &&
440
    (RemoteLinkLost == 0) )
441
  {  /* Average the average throttle to find the hover setting */
442
    AverageGasMischanteil = 0.999F * AverageGasMischanteil + 0.001F * GasMischanteil;
443
  }
444
  /* Overide GasMischanteil */
445
  static unsigned int DescentCnt = 32000;
446
  if ((RemoteLinkLost == 1) &&
447
    (MotorenEin == 1))
448
  {
449
    if ((UBat < 100) || /* Start to descent in case of low loltage or in case*/
450
    (maxDistance / 10 < 12)) /* we reached our target position */
451
    {
452
      if (DescentCnt > 0)
453
      {
454
        DescentCnt--;
455
      }
456
      else
457
      {  /* We reached our target (hopefully) */
458
        MotorenEin = 0;
459
        RemoteLinkLost = 0;
460
      }
461
    }
462
    else
463
    {
464
      DescentCnt = 32000;
465
    }
466
    /* Bias the throttle for a slow descent */
467
    GasMischanteil = (int) ((AverageGasMischanteil + 5.0F) * (DescentCnt / 32000.F));
468
  }
469
  else
470
  {
471
    DescentCnt = 32000;
472
  }
473
 
474
  //DebugOut.Analog[13] = (int) GasMischanteil;
475
 
972 MikeW 476
#ifdef X_FORMATION
966 MikeW 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
  }
972 MikeW 489
#else
490
  /* Overide in case the remote link got lost */
491
  if (RemoteLinkLost == 0)
492
  { /* We are flying in X-Formation */
493
    StickRoll45 = StickRoll - GPS_Roll;
494
    StickNick45 = StickNick - GPS_Nick;
495
  }
496
  else
497
  {  /* GPS overide is aktive */
498
    StickRoll45 = -GPS_Roll;
499
    StickNick45 = -GPS_Nick;
500
    StickGier = 0;
501
  }
502
#endif
503
 
966 MikeW 504
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
505
  //  Yaw
506
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
507
 
508
  if(GasMischanteil < 20)
509
  {
510
    sollGier = status.iPsi10;
511
    SummeRoll = 0;
512
    SummeNick = 0;
513
  }
514
 
515
  /* Gier-Anteil */
516
  if (abs(StickGier) > 4)
517
  {
518
    sollGier = status.iPsi10 + 4 * StickGier;  
519
  }
520
  DiffGier = (sollGier - status.iPsi10);
521
  GierMischanteil = (int) (-4 *  DiffGier - 4* (AdWertGier - AdNeutralGier - Roll_Z_Off)) / 10;
522
 
523
#define MUL_G  0.8
524
  if(GierMischanteil > MUL_G * GasMischanteil)
525
  {
526
    GierMischanteil = MUL_G * GasMischanteil;
527
  }
528
  if(GierMischanteil < -MUL_G * GasMischanteil)
529
  {
530
    GierMischanteil = -MUL_G * GasMischanteil;
531
  }
532
  if(GierMischanteil > 50)
533
  {
534
    GierMischanteil = 50;
535
  }
536
  if(GierMischanteil < -50)
537
  {
538
    GierMischanteil = -50;
539
  }
540
 
541
  /*****************************************************************************
542
  PD-Control
543
  **************************************************************************** */
544
  int scale_p;
545
  int scale_d;
546
 
547
  scale_p = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 170)) / 20);
548
  scale_d = (MAX(0, (PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 170)) / 20);  
549
 
550
  scale_p = 6;
551
  scale_d = 7;
552
 
553
  //DebugOut.Analog[14] =  scale_p;
554
  //DebugOut.Analog[15] =  scale_d;
555
 
556
  /* Pitch */
557
  DiffNick = -(status.iTheta10 + StickNick45);
558
  /* R o l l */
559
  DiffRoll = -(status.iPhi10 + StickRoll45);
560
 
561
  SummeNick += DiffNick;
562
  if(SummeNick >  10000)
563
  {
564
    SummeNick =  10000;
565
  }
566
  if(SummeNick < -10000)
567
  {
568
    SummeNick = -10000;
569
  }
570
 
571
  SummeRoll += DiffRoll;  
572
  if(SummeRoll >  10000)
573
  {
574
    SummeRoll =  10000;
575
  }
576
  if(SummeRoll < -10000)
577
  {
578
    SummeRoll = -10000;
579
  }
580
 
581
  pd_ergebnis = ((scale_p *DiffNick + scale_d * (AdWertNick - AdNeutralNick - Roll_Y_Off)) / 10) ; // + (int)(SummeNick / 2000); 
582
  if(pd_ergebnis >  (GasMischanteil + abs(GierMischanteil)))
583
  {
584
    pd_ergebnis =  (GasMischanteil + abs(GierMischanteil));
585
  }
586
  if(pd_ergebnis < -(GasMischanteil + abs(GierMischanteil)))
587
  {
588
    pd_ergebnis = -(GasMischanteil + abs(GierMischanteil));
589
  }
590
 
591
  /* M o t o r   V o r n */
592
  motorwert = GasMischanteil + pd_ergebnis + GierMischanteil;
593
  if ((motorwert < 0))
594
  {
595
    motorwert = 0;
596
  }
597
  else if(motorwert > MAX_GAS)
598
  {
599
    motorwert = MAX_GAS;
600
  }
601
  if (motorwert < MIN_GAS)
602
  {
603
    motorwert = MIN_GAS;
604
  }
605
  Motor_Vorne = motorwert;  
606
 
607
  /* M o t o r   H e c k */
608
  motorwert = GasMischanteil - pd_ergebnis + GierMischanteil;
609
  if ((motorwert < 0))
610
  {
611
    motorwert = 0;
612
  }
613
  else if(motorwert > MAX_GAS)
614
  {
615
    motorwert = MAX_GAS;
616
  }
617
  if (motorwert < MIN_GAS)
618
  {
619
    motorwert = MIN_GAS;
620
  }
621
  Motor_Hinten = motorwert;
622
 
623
  pd_ergebnis =  ((scale_p * DiffRoll + scale_d * (AdWertRoll - AdNeutralRoll - Roll_X_Off)) / 10) ; //+ (int)(SummeRoll / 2000);
624
  if(pd_ergebnis >  (GasMischanteil + abs(GierMischanteil)))
625
  {
626
    pd_ergebnis =  (GasMischanteil + abs(GierMischanteil));
627
  }
628
  if(pd_ergebnis < -(GasMischanteil + abs(GierMischanteil)))
629
  {
630
    pd_ergebnis = -(GasMischanteil + abs(GierMischanteil));
631
  }
632
 
633
  /* M o t o r   L i n k s */
634
  motorwert = GasMischanteil + pd_ergebnis - GierMischanteil;
635
  if(motorwert > MAX_GAS)
636
  {
637
    motorwert = MAX_GAS;
638
  }
639
  if (motorwert < MIN_GAS)
640
  {
641
    motorwert = MIN_GAS;
642
  }
643
  Motor_Links = motorwert;
644
 
645
  /* M o t o r   R e c h t s */
646
  motorwert = GasMischanteil - pd_ergebnis - GierMischanteil;
647
  if(motorwert > MAX_GAS)
648
  {
649
    motorwert = MAX_GAS;
650
  }
651
  if (motorwert < MIN_GAS)
652
  {
653
    motorwert = MIN_GAS;
654
  }
655
  Motor_Rechts = motorwert;
656
 
657
#if 1
658
  DebugOut.Analog[0] = status.iTheta10;
659
  DebugOut.Analog[1] = status.iPhi10;
660
  DebugOut.Analog[2] = status.iPsi10 / 10;
661
#endif
662
}