]> git.mxchange.org Git - flightgear.git/blob - src/Controls/controls.cxx
Check point commit:
[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     throttle_idle = true;
82     set_fuel_selector( ALL_TANKS, true );
83     gear_down = true;
84 }
85
86
87 // Destructor
88 FGControls::~FGControls() {
89 }
90
91
92 void
93 FGControls::init ()
94 {
95     for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
96         throttle[engine] = 0.0;
97         mixture[engine] = 1.0;
98         prop_advance[engine] = 1.0;
99         magnetos[engine] = 0;
100         starter[engine] = false;
101     }
102
103     for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
104         brake[wheel] = 0.0;
105     }
106
107     auto_coordination = fgGetNode("/sim/auto-coordination", true);
108 }
109
110
111 void
112 FGControls::bind ()
113 {
114   fgTie("/controls/aileron", this,
115         &FGControls::get_aileron, &FGControls::set_aileron);
116   fgSetArchivable("/controls/aileron");
117   fgTie("/controls/aileron-trim", this,
118        &FGControls::get_aileron_trim, &FGControls::set_aileron_trim);
119   fgSetArchivable("/controls/aileron-trim");
120   fgTie("/controls/elevator", this,
121        &FGControls::get_elevator, &FGControls::set_elevator);
122   fgSetArchivable("/controls/elevator");
123   fgTie("/controls/elevator-trim", this,
124        &FGControls::get_elevator_trim, &FGControls::set_elevator_trim);
125   fgSetArchivable("/controls/elevator-trim");
126   fgTie("/controls/rudder", this,
127        &FGControls::get_rudder, &FGControls::set_rudder);
128   fgSetArchivable("/controls/rudder");
129   fgTie("/controls/rudder-trim", this,
130        &FGControls::get_rudder_trim, &FGControls::set_rudder_trim);
131   fgSetArchivable("/controls/rudder-trim");
132   fgTie("/controls/flaps", this,
133        &FGControls::get_flaps, &FGControls::set_flaps);
134   fgSetArchivable("/controls/flaps");
135   int index;
136   for (index = 0; index < MAX_ENGINES; index++) {
137     char name[32];
138     sprintf(name, "/controls/throttle[%d]", index);
139     fgTie(name, this, index,
140           &FGControls::get_throttle, &FGControls::set_throttle);
141     fgSetArchivable(name);
142     sprintf(name, "/controls/mixture[%d]", index);
143     fgTie(name, this, index,
144          &FGControls::get_mixture, &FGControls::set_mixture);
145     fgSetArchivable(name);
146     sprintf(name, "/controls/propeller-pitch[%d]", index);
147     fgTie(name, this, index,
148          &FGControls::get_prop_advance, &FGControls::set_prop_advance);
149     fgSetArchivable(name);
150     sprintf(name, "/controls/magnetos[%d]", index);
151     fgTie(name, this, index,
152          &FGControls::get_magnetos, &FGControls::set_magnetos);
153     fgSetArchivable(name);
154     sprintf(name, "/controls/starter[%d]", index);
155     fgTie(name, this, index,
156          &FGControls::get_starter, &FGControls::set_starter);
157     fgSetArchivable(name);
158   }
159   fgTie("/controls/parking-brake", this,
160         &FGControls::get_parking_brake, &FGControls::set_parking_brake);
161   fgSetArchivable("/controls/parking-brake");
162   for (index = 0; index < MAX_WHEELS; index++) {
163       char name[32];
164       sprintf(name, "/controls/brakes[%d]", index);
165       fgTie(name, this, index,
166             &FGControls::get_brake, &FGControls::set_brake);
167       fgSetArchivable(name);
168   }
169   for (index = 0; index < MAX_TANKS; index++) {
170       char name[32];
171       sprintf(name, "/controls/fuel-selector[%d]", index);
172       fgTie(name, this, index,
173             &FGControls::get_fuel_selector, &FGControls::set_fuel_selector);
174       fgSetArchivable(name);
175   }
176   fgTie("/controls/gear-down", this,
177         &FGControls::get_gear_down, &FGControls::set_gear_down);
178   fgSetArchivable("/controls/gear-down");
179 }
180
181
182 void
183 FGControls::unbind ()
184 {
185                                 // Tie control properties.
186   fgUntie("/controls/aileron");
187   fgUntie("/controls/aileron-trim");
188   fgUntie("/controls/elevator");
189   fgUntie("/controls/elevator-trim");
190   fgUntie("/controls/rudder");
191   fgUntie("/controls/rudder-trim");
192   fgUntie("/controls/flaps");
193   int index;
194   for (index = 0; index < MAX_ENGINES; index++) {
195     char name[32];
196     sprintf(name, "/controls/throttle[%d]", index);
197     fgUntie(name);
198     sprintf(name, "/controls/mixture[%d]", index);
199     fgUntie(name);
200     sprintf(name, "/controls/propeller-pitch[%d]", index);
201     fgUntie(name);
202     sprintf(name, "/controls/magnetos[%d]", index);
203     fgUntie(name);
204     sprintf(name, "/controls/starter[%d]", index);
205     fgUntie(name);
206   }
207   for (index = 0; index < MAX_WHEELS; index++) {
208     char name[32];
209     sprintf(name, "/controls/brakes[%d]", index);
210     fgUntie(name);
211   }
212   fgUntie("/controls/fuel-selector");
213   fgUntie("/controls/gear-down");
214 }
215
216
217 void
218 FGControls::update (double dt)
219 {
220 }
221
222
223 \f
224 ////////////////////////////////////////////////////////////////////////
225 // Setters and adjusters.
226 ////////////////////////////////////////////////////////////////////////
227
228 void
229 FGControls::set_aileron (double pos)
230 {
231   aileron = pos;
232   CLAMP( &aileron, -1.0, 1.0 );
233                         
234   // check for autocoordination
235   if ( auto_coordination->getBoolValue() ) {
236     set_rudder( aileron / 2.0 );
237   }
238 }
239
240 void
241 FGControls::move_aileron (double amt)
242 {
243   aileron += amt;
244   CLAMP( &aileron, -1.0, 1.0 );
245                         
246   // check for autocoordination
247   if ( auto_coordination->getBoolValue() ) {
248     set_rudder( aileron / 2.0 );
249   }
250 }
251
252 void
253 FGControls::set_aileron_trim( double pos )
254 {
255     aileron_trim = pos;
256     CLAMP( &aileron_trim, -1.0, 1.0 );
257 }
258
259 void
260 FGControls::move_aileron_trim( double amt )
261 {
262     aileron_trim += amt;
263     CLAMP( &aileron_trim, -1.0, 1.0 );
264 }
265
266 void
267 FGControls::set_elevator( double pos )
268 {
269     elevator = pos;
270     CLAMP( &elevator, -1.0, 1.0 );
271 }
272
273 void
274 FGControls::move_elevator( double amt )
275 {
276     elevator += amt;
277     CLAMP( &elevator, -1.0, 1.0 );
278 }
279
280 void
281 FGControls::set_elevator_trim( double pos )
282 {
283     elevator_trim = pos;
284     CLAMP( &elevator_trim, -1.0, 1.0 );
285 }
286
287 void
288 FGControls::move_elevator_trim( double amt )
289 {
290     elevator_trim += amt;
291     CLAMP( &elevator_trim, -1.0, 1.0 );
292 }
293
294 void
295 FGControls::set_rudder( double pos )
296 {
297     rudder = pos;
298     CLAMP( &rudder, -1.0, 1.0 );
299 }
300
301 void
302 FGControls::move_rudder( double amt )
303 {
304     rudder += amt;
305     CLAMP( &rudder, -1.0, 1.0 );
306 }
307
308 void
309 FGControls::set_rudder_trim( double pos )
310 {
311     rudder_trim = pos;
312     CLAMP( &rudder_trim, -1.0, 1.0 );
313 }
314
315 void
316 FGControls::move_rudder_trim( double amt )
317 {
318     rudder_trim += amt;
319     CLAMP( &rudder_trim, -1.0, 1.0 );
320 }
321
322 void
323 FGControls::set_flaps( double pos )
324 {
325     flaps = pos;
326     CLAMP( &flaps, 0.0, 1.0 );
327 }
328
329 void
330 FGControls::move_flaps( double amt )
331 {
332     flaps += amt;
333     CLAMP( &flaps, 0.0, 1.0 );
334 }
335
336 void
337 FGControls::set_throttle( int engine, double pos )
338 {
339   if ( engine == ALL_ENGINES ) {
340     for ( int i = 0; i < MAX_ENGINES; i++ ) {
341       throttle[i] = pos;
342       CLAMP( &throttle[i], 0.0, 1.0 );
343     }
344   } else {
345     if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
346       throttle[engine] = pos;
347       CLAMP( &throttle[engine], 0.0, 1.0 );
348     }
349   }
350 }
351
352 void
353 FGControls::move_throttle( int engine, double amt )
354 {
355     if ( engine == ALL_ENGINES ) {
356         for ( int i = 0; i < MAX_ENGINES; i++ ) {
357             throttle[i] += amt;
358             CLAMP( &throttle[i], 0.0, 1.0 );
359         }
360     } else {
361         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
362             throttle[engine] += amt;
363             CLAMP( &throttle[engine], 0.0, 1.0 );
364         }
365     }
366 }
367
368 void
369 FGControls::set_mixture( int engine, double pos )
370 {
371     if ( engine == ALL_ENGINES ) {
372         for ( int i = 0; i < MAX_ENGINES; i++ ) {
373             mixture[i] = pos;
374             CLAMP( &mixture[i], 0.0, 1.0 );
375         }
376     } else {
377         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
378             mixture[engine] = pos;
379             CLAMP( &mixture[engine], 0.0, 1.0 );
380         }
381     }
382 }
383
384 void
385 FGControls::move_mixture( int engine, double amt )
386 {
387     if ( engine == ALL_ENGINES ) {
388         for ( int i = 0; i < MAX_ENGINES; i++ ) {
389             mixture[i] += amt;
390             CLAMP( &mixture[i], 0.0, 1.0 );
391         }
392     } else {
393         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
394             mixture[engine] += amt;
395             CLAMP( &mixture[engine], 0.0, 1.0 );
396         }
397     }
398 }
399
400 void
401 FGControls::set_prop_advance( int engine, double pos )
402 {
403     if ( engine == ALL_ENGINES ) {
404         for ( int i = 0; i < MAX_ENGINES; i++ ) {
405             prop_advance[i] = pos;
406             CLAMP( &prop_advance[i], 0.0, 1.0 );
407         }
408     } else {
409         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
410             prop_advance[engine] = pos;
411             CLAMP( &prop_advance[engine], 0.0, 1.0 );
412         }
413     }
414 }
415
416 void
417 FGControls::move_prop_advance( int engine, double amt )
418 {
419     if ( engine == ALL_ENGINES ) {
420         for ( int i = 0; i < MAX_ENGINES; i++ ) {
421             prop_advance[i] += amt;
422             CLAMP( &prop_advance[i], 0.0, 1.0 );
423         }
424     } else {
425         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
426             prop_advance[engine] += amt;
427             CLAMP( &prop_advance[engine], 0.0, 1.0 );
428         }
429     }
430 }
431
432 void
433 FGControls::set_magnetos( int engine, int pos )
434 {
435     if ( engine == ALL_ENGINES ) {
436         for ( int i = 0; i < MAX_ENGINES; i++ ) {
437             magnetos[i] = pos;
438             CLAMP( &magnetos[i], 0, 3 );
439         }
440     } else {
441         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
442             magnetos[engine] = pos;
443             CLAMP( &magnetos[engine], 0, 3 );
444         }
445     }
446 }
447
448 void
449 FGControls::move_magnetos( int engine, int amt )
450 {
451     if ( engine == ALL_ENGINES ) {
452         for ( int i = 0; i < MAX_ENGINES; i++ ) {
453             magnetos[i] += amt;
454             CLAMP( &magnetos[i], 0, 3 );
455         }
456     } else {
457         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
458             magnetos[engine] += amt;
459             CLAMP( &magnetos[engine], 0, 3 );
460         }
461     }
462 }
463
464 void
465 FGControls::set_starter( int engine, bool flag )
466 {
467     if ( engine == ALL_ENGINES ) {
468         for ( int i = 0; i < MAX_ENGINES; i++ ) {
469             starter[i] = flag;
470         }
471     } else {
472         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
473             starter[engine] = flag;
474         }
475     }
476 }
477
478 void
479 FGControls::set_fuel_selector( int tank, bool pos )
480 {
481     if ( tank == ALL_TANKS ) {
482         for ( int i = 0; i < MAX_TANKS; i++ ) {
483             fuel_selector[i] = pos;
484         }
485     } else {
486         if ( (tank >= 0) && (tank < MAX_TANKS) ) {
487             fuel_selector[tank] = pos;
488         }
489     }
490 }
491
492
493 void
494 FGControls::set_parking_brake( double pos )
495 {
496     parking_brake = pos;
497     CLAMP(&parking_brake, 0.0, 1.0);
498 }
499
500 void
501 FGControls::set_brake( int wheel, double pos )
502 {
503     if ( wheel == ALL_WHEELS ) {
504         for ( int i = 0; i < MAX_WHEELS; i++ ) {
505             brake[i] = pos;
506             CLAMP( &brake[i], 0.0, 1.0 );
507         }
508     } else {
509         if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
510             brake[wheel] = pos;
511             CLAMP( &brake[wheel], 0.0, 1.0 );
512         }
513     }
514 }
515
516 void
517 FGControls::move_brake( int wheel, double amt )
518 {
519     if ( wheel == ALL_WHEELS ) {
520         for ( int i = 0; i < MAX_WHEELS; i++ ) {
521             brake[i] += amt;
522             CLAMP( &brake[i], 0.0, 1.0 );
523         }
524     } else {
525         if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
526             brake[wheel] += amt;
527             CLAMP( &brake[wheel], 0.0, 1.0 );
528         }
529     }
530 }
531
532 void
533 FGControls::set_gear_down( bool gear )
534 {
535   gear_down = gear;
536 }
537
538