]> git.mxchange.org Git - flightgear.git/blob - src/Controls/controls.cxx
Make sure that all elapsed time gets passed to update when a subsystem
[flightgear.git] / src / Controls / controls.cxx
1 // controls.cxx -- defines a standard interface to all flight sim controls
2 //
3 // Written by Curtis Olson, started May 1997.
4 //
5 // Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23
24 #include "controls.hxx"
25
26 #include <simgear/debug/logstream.hxx>
27 #include <Main/fg_props.hxx>
28
29
30 \f
31 ////////////////////////////////////////////////////////////////////////
32 // Inline utility methods.
33 ////////////////////////////////////////////////////////////////////////
34
35 static inline void
36 CLAMP(double *x, double min, double max )
37 {
38   if ( *x < min ) { *x = min; }
39   if ( *x > max ) { *x = max; }
40 }
41
42 static inline void
43 CLAMP(int *i, int min, int max )
44 {
45   if ( *i < min ) { *i = min; }
46   if ( *i > max ) { *i = max; }
47 }
48
49 \f
50 ////////////////////////////////////////////////////////////////////////
51 // Implementation of FGControls.
52 ////////////////////////////////////////////////////////////////////////
53
54 // Constructor
55 FGControls::FGControls() :
56     aileron( 0.0 ),
57     aileron_trim( 0.0 ),
58     elevator( 0.0 ),
59     elevator_trim( 0.0 ),
60     rudder( 0.0 ),
61     rudder_trim( 0.0 ),
62     flaps( 0.0 ),
63     parking_brake( 0.0 ),
64     throttle_idle( true ),
65     gear_down( false )
66 {
67 }
68
69
70 void FGControls::reset_all()
71 {
72     set_aileron( 0.0 );
73     set_aileron_trim( 0.0 );
74     set_elevator( 0.0 );
75     set_elevator_trim( 0.0 );
76     set_rudder( 0.0 );
77     set_rudder_trim( 0.0 );
78     set_throttle( ALL_ENGINES, 0.0 );
79     set_starter( ALL_ENGINES, false );
80     set_magnetos( ALL_ENGINES, 0 );
81     set_fuel_pump( ALL_ENGINES, false );
82     throttle_idle = true;
83     set_fuel_selector( ALL_TANKS, true );
84     gear_down = true;
85 }
86
87
88 // Destructor
89 FGControls::~FGControls() {
90 }
91
92
93 void
94 FGControls::init ()
95 {
96     for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
97         throttle[engine] = 0.0;
98         mixture[engine] = 1.0;
99         fuel_pump[engine] = false;
100         prop_advance[engine] = 1.0;
101         magnetos[engine] = 0;
102         starter[engine] = false;
103     }
104
105     for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
106         brake[wheel] = 0.0;
107     }
108
109     auto_coordination = fgGetNode("/sim/auto-coordination", true);
110 }
111
112
113 void
114 FGControls::bind ()
115 {
116   fgTie("/controls/aileron", this,
117         &FGControls::get_aileron, &FGControls::set_aileron);
118   fgSetArchivable("/controls/aileron");
119   fgTie("/controls/aileron-trim", this,
120        &FGControls::get_aileron_trim, &FGControls::set_aileron_trim);
121   fgSetArchivable("/controls/aileron-trim");
122   fgTie("/controls/elevator", this,
123        &FGControls::get_elevator, &FGControls::set_elevator);
124   fgSetArchivable("/controls/elevator");
125   fgTie("/controls/elevator-trim", this,
126        &FGControls::get_elevator_trim, &FGControls::set_elevator_trim);
127   fgSetArchivable("/controls/elevator-trim");
128   fgTie("/controls/rudder", this,
129        &FGControls::get_rudder, &FGControls::set_rudder);
130   fgSetArchivable("/controls/rudder");
131   fgTie("/controls/rudder-trim", this,
132        &FGControls::get_rudder_trim, &FGControls::set_rudder_trim);
133   fgSetArchivable("/controls/rudder-trim");
134   fgTie("/controls/flaps", this,
135        &FGControls::get_flaps, &FGControls::set_flaps);
136   fgSetArchivable("/controls/flaps");
137   int index;
138   for (index = 0; index < MAX_ENGINES; index++) {
139     char name[32];
140     sprintf(name, "/controls/throttle[%d]", index);
141     fgTie(name, this, index,
142           &FGControls::get_throttle, &FGControls::set_throttle);
143     fgSetArchivable(name);
144     sprintf(name, "/controls/mixture[%d]", index);
145     fgTie(name, this, index,
146          &FGControls::get_mixture, &FGControls::set_mixture);
147     fgSetArchivable(name);
148     sprintf(name, "/controls/fuel-pump[%d]", index);
149     fgTie(name, this, index,
150          &FGControls::get_fuel_pump, &FGControls::set_fuel_pump);
151     fgSetArchivable(name);
152     sprintf(name, "/controls/propeller-pitch[%d]", index);
153     fgTie(name, this, index,
154          &FGControls::get_prop_advance, &FGControls::set_prop_advance);
155     fgSetArchivable(name);
156     sprintf(name, "/controls/magnetos[%d]", index);
157     fgTie(name, this, index,
158          &FGControls::get_magnetos, &FGControls::set_magnetos);
159     fgSetArchivable(name);
160     sprintf(name, "/controls/starter[%d]", index);
161     fgTie(name, this, index,
162          &FGControls::get_starter, &FGControls::set_starter);
163     fgSetArchivable(name);
164   }
165   fgTie("/controls/parking-brake", this,
166         &FGControls::get_parking_brake, &FGControls::set_parking_brake);
167   fgSetArchivable("/controls/parking-brake");
168   for (index = 0; index < MAX_WHEELS; index++) {
169       char name[32];
170       sprintf(name, "/controls/brakes[%d]", index);
171       fgTie(name, this, index,
172             &FGControls::get_brake, &FGControls::set_brake);
173       fgSetArchivable(name);
174   }
175   for (index = 0; index < MAX_TANKS; index++) {
176       char name[32];
177       sprintf(name, "/controls/fuel-selector[%d]", index);
178       fgTie(name, this, index,
179             &FGControls::get_fuel_selector, &FGControls::set_fuel_selector);
180       fgSetArchivable(name);
181   }
182   fgTie("/controls/gear-down", this,
183         &FGControls::get_gear_down, &FGControls::set_gear_down);
184   fgSetArchivable("/controls/gear-down");
185 }
186
187
188 void
189 FGControls::unbind ()
190 {
191                                 // Tie control properties.
192   fgUntie("/controls/aileron");
193   fgUntie("/controls/aileron-trim");
194   fgUntie("/controls/elevator");
195   fgUntie("/controls/elevator-trim");
196   fgUntie("/controls/rudder");
197   fgUntie("/controls/rudder-trim");
198   fgUntie("/controls/flaps");
199   int index;
200   for (index = 0; index < MAX_ENGINES; index++) {
201     char name[32];
202     sprintf(name, "/controls/throttle[%d]", index);
203     fgUntie(name);
204     sprintf(name, "/controls/mixture[%d]", index);
205     fgUntie(name);
206     sprintf(name, "/controls/fuel-pump[%d]", index);
207     fgUntie(name);
208     sprintf(name, "/controls/propeller-pitch[%d]", index);
209     fgUntie(name);
210     sprintf(name, "/controls/magnetos[%d]", index);
211     fgUntie(name);
212     sprintf(name, "/controls/starter[%d]", index);
213     fgUntie(name);
214   }
215   for (index = 0; index < MAX_WHEELS; index++) {
216     char name[32];
217     sprintf(name, "/controls/brakes[%d]", index);
218     fgUntie(name);
219   }
220   fgUntie("/controls/fuel-selector");
221   fgUntie("/controls/gear-down");
222 }
223
224
225 void
226 FGControls::update (double dt)
227 {
228 }
229
230
231 \f
232 ////////////////////////////////////////////////////////////////////////
233 // Setters and adjusters.
234 ////////////////////////////////////////////////////////////////////////
235
236 void
237 FGControls::set_aileron (double pos)
238 {
239   aileron = pos;
240   CLAMP( &aileron, -1.0, 1.0 );
241                         
242   // check for autocoordination
243   if ( auto_coordination->getBoolValue() ) {
244     set_rudder( aileron / 2.0 );
245   }
246 }
247
248 void
249 FGControls::move_aileron (double amt)
250 {
251   aileron += amt;
252   CLAMP( &aileron, -1.0, 1.0 );
253                         
254   // check for autocoordination
255   if ( auto_coordination->getBoolValue() ) {
256     set_rudder( aileron / 2.0 );
257   }
258 }
259
260 void
261 FGControls::set_aileron_trim( double pos )
262 {
263     aileron_trim = pos;
264     CLAMP( &aileron_trim, -1.0, 1.0 );
265 }
266
267 void
268 FGControls::move_aileron_trim( double amt )
269 {
270     aileron_trim += amt;
271     CLAMP( &aileron_trim, -1.0, 1.0 );
272 }
273
274 void
275 FGControls::set_elevator( double pos )
276 {
277     elevator = pos;
278     CLAMP( &elevator, -1.0, 1.0 );
279 }
280
281 void
282 FGControls::move_elevator( double amt )
283 {
284     elevator += amt;
285     CLAMP( &elevator, -1.0, 1.0 );
286 }
287
288 void
289 FGControls::set_elevator_trim( double pos )
290 {
291     elevator_trim = pos;
292     CLAMP( &elevator_trim, -1.0, 1.0 );
293 }
294
295 void
296 FGControls::move_elevator_trim( double amt )
297 {
298     elevator_trim += amt;
299     CLAMP( &elevator_trim, -1.0, 1.0 );
300 }
301
302 void
303 FGControls::set_rudder( double pos )
304 {
305     rudder = pos;
306     CLAMP( &rudder, -1.0, 1.0 );
307 }
308
309 void
310 FGControls::move_rudder( double amt )
311 {
312     rudder += amt;
313     CLAMP( &rudder, -1.0, 1.0 );
314 }
315
316 void
317 FGControls::set_rudder_trim( double pos )
318 {
319     rudder_trim = pos;
320     CLAMP( &rudder_trim, -1.0, 1.0 );
321 }
322
323 void
324 FGControls::move_rudder_trim( double amt )
325 {
326     rudder_trim += amt;
327     CLAMP( &rudder_trim, -1.0, 1.0 );
328 }
329
330 void
331 FGControls::set_flaps( double pos )
332 {
333     flaps = pos;
334     CLAMP( &flaps, 0.0, 1.0 );
335 }
336
337 void
338 FGControls::move_flaps( double amt )
339 {
340     flaps += amt;
341     CLAMP( &flaps, 0.0, 1.0 );
342 }
343
344 void
345 FGControls::set_throttle( int engine, double pos )
346 {
347   if ( engine == ALL_ENGINES ) {
348     for ( int i = 0; i < MAX_ENGINES; i++ ) {
349       throttle[i] = pos;
350       CLAMP( &throttle[i], 0.0, 1.0 );
351     }
352   } else {
353     if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
354       throttle[engine] = pos;
355       CLAMP( &throttle[engine], 0.0, 1.0 );
356     }
357   }
358 }
359
360 void
361 FGControls::move_throttle( int engine, double amt )
362 {
363     if ( engine == ALL_ENGINES ) {
364         for ( int i = 0; i < MAX_ENGINES; i++ ) {
365             throttle[i] += amt;
366             CLAMP( &throttle[i], 0.0, 1.0 );
367         }
368     } else {
369         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
370             throttle[engine] += amt;
371             CLAMP( &throttle[engine], 0.0, 1.0 );
372         }
373     }
374 }
375
376 void
377 FGControls::set_mixture( int engine, double pos )
378 {
379     if ( engine == ALL_ENGINES ) {
380         for ( int i = 0; i < MAX_ENGINES; i++ ) {
381             mixture[i] = pos;
382             CLAMP( &mixture[i], 0.0, 1.0 );
383         }
384     } else {
385         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
386             mixture[engine] = pos;
387             CLAMP( &mixture[engine], 0.0, 1.0 );
388         }
389     }
390 }
391
392 void
393 FGControls::move_mixture( int engine, double amt )
394 {
395     if ( engine == ALL_ENGINES ) {
396         for ( int i = 0; i < MAX_ENGINES; i++ ) {
397             mixture[i] += amt;
398             CLAMP( &mixture[i], 0.0, 1.0 );
399         }
400     } else {
401         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
402             mixture[engine] += amt;
403             CLAMP( &mixture[engine], 0.0, 1.0 );
404         }
405     }
406 }
407
408 void
409 FGControls::set_fuel_pump( int engine, bool val )
410 {
411     if ( engine == ALL_ENGINES ) {
412         for ( int i = 0; i < MAX_ENGINES; i++ ) {
413             fuel_pump[i] = val;
414         }
415     } else {
416         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
417             fuel_pump[engine] = val;
418         }
419     }
420 }
421
422 void
423 FGControls::set_prop_advance( int engine, double pos )
424 {
425     if ( engine == ALL_ENGINES ) {
426         for ( int i = 0; i < MAX_ENGINES; i++ ) {
427             prop_advance[i] = pos;
428             CLAMP( &prop_advance[i], 0.0, 1.0 );
429         }
430     } else {
431         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
432             prop_advance[engine] = pos;
433             CLAMP( &prop_advance[engine], 0.0, 1.0 );
434         }
435     }
436 }
437
438 void
439 FGControls::move_prop_advance( int engine, double amt )
440 {
441     if ( engine == ALL_ENGINES ) {
442         for ( int i = 0; i < MAX_ENGINES; i++ ) {
443             prop_advance[i] += amt;
444             CLAMP( &prop_advance[i], 0.0, 1.0 );
445         }
446     } else {
447         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
448             prop_advance[engine] += amt;
449             CLAMP( &prop_advance[engine], 0.0, 1.0 );
450         }
451     }
452 }
453
454 void
455 FGControls::set_magnetos( int engine, int pos )
456 {
457     if ( engine == ALL_ENGINES ) {
458         for ( int i = 0; i < MAX_ENGINES; i++ ) {
459             magnetos[i] = pos;
460             CLAMP( &magnetos[i], 0, 3 );
461         }
462     } else {
463         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
464             magnetos[engine] = pos;
465             CLAMP( &magnetos[engine], 0, 3 );
466         }
467     }
468 }
469
470 void
471 FGControls::move_magnetos( int engine, int amt )
472 {
473     if ( engine == ALL_ENGINES ) {
474         for ( int i = 0; i < MAX_ENGINES; i++ ) {
475             magnetos[i] += amt;
476             CLAMP( &magnetos[i], 0, 3 );
477         }
478     } else {
479         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
480             magnetos[engine] += amt;
481             CLAMP( &magnetos[engine], 0, 3 );
482         }
483     }
484 }
485
486 void
487 FGControls::set_starter( int engine, bool flag )
488 {
489     if ( engine == ALL_ENGINES ) {
490         for ( int i = 0; i < MAX_ENGINES; i++ ) {
491             starter[i] = flag;
492         }
493     } else {
494         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
495             starter[engine] = flag;
496         }
497     }
498 }
499
500 void
501 FGControls::set_fuel_selector( int tank, bool pos )
502 {
503     if ( tank == ALL_TANKS ) {
504         for ( int i = 0; i < MAX_TANKS; i++ ) {
505             fuel_selector[i] = pos;
506         }
507     } else {
508         if ( (tank >= 0) && (tank < MAX_TANKS) ) {
509             fuel_selector[tank] = pos;
510         }
511     }
512 }
513
514
515 void
516 FGControls::set_parking_brake( double pos )
517 {
518     parking_brake = pos;
519     CLAMP(&parking_brake, 0.0, 1.0);
520 }
521
522 void
523 FGControls::set_brake( int wheel, double pos )
524 {
525     if ( wheel == ALL_WHEELS ) {
526         for ( int i = 0; i < MAX_WHEELS; i++ ) {
527             brake[i] = pos;
528             CLAMP( &brake[i], 0.0, 1.0 );
529         }
530     } else {
531         if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
532             brake[wheel] = pos;
533             CLAMP( &brake[wheel], 0.0, 1.0 );
534         }
535     }
536 }
537
538 void
539 FGControls::move_brake( int wheel, double amt )
540 {
541     if ( wheel == ALL_WHEELS ) {
542         for ( int i = 0; i < MAX_WHEELS; i++ ) {
543             brake[i] += amt;
544             CLAMP( &brake[i], 0.0, 1.0 );
545         }
546     } else {
547         if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
548             brake[wheel] += amt;
549             CLAMP( &brake[wheel], 0.0, 1.0 );
550         }
551     }
552 }
553
554 void
555 FGControls::set_gear_down( bool gear )
556 {
557   gear_down = gear;
558 }
559
560