1 // controls.cxx -- defines a standard interface to all flight sim controls
3 // Written by Curtis Olson, started May 1997.
5 // Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
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.
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.
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.
24 #include "controls.hxx"
26 #include <simgear/debug/logstream.hxx>
27 #include <Main/fg_props.hxx>
31 ////////////////////////////////////////////////////////////////////////
32 // Inline utility methods.
33 ////////////////////////////////////////////////////////////////////////
36 CLAMP(double *x, double min, double max )
38 if ( *x < min ) { *x = min; }
39 if ( *x > max ) { *x = max; }
43 CLAMP(int *i, int min, int max )
45 if ( *i < min ) { *i = min; }
46 if ( *i > max ) { *i = max; }
50 ////////////////////////////////////////////////////////////////////////
51 // Implementation of FGControls.
52 ////////////////////////////////////////////////////////////////////////
55 FGControls::FGControls() :
66 throttle_idle( true ),
72 void FGControls::reset_all()
75 set_aileron_trim( 0.0 );
77 set_elevator_trim( 0.0 );
79 set_rudder_trim( 0.0 );
80 set_throttle( ALL_ENGINES, 0.0 );
81 set_starter( ALL_ENGINES, false );
82 set_magnetos( ALL_ENGINES, 0 );
83 set_fuel_pump( ALL_ENGINES, false );
85 set_fuel_selector( ALL_TANKS, true );
91 FGControls::~FGControls() {
98 for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
99 throttle[engine] = 0.0;
100 mixture[engine] = 1.0;
101 fuel_pump[engine] = false;
102 prop_advance[engine] = 1.0;
103 magnetos[engine] = 0;
104 starter[engine] = false;
107 for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
111 auto_coordination = fgGetNode("/sim/auto-coordination", true);
118 fgTie("/controls/aileron", this,
119 &FGControls::get_aileron, &FGControls::set_aileron);
120 fgSetArchivable("/controls/aileron");
121 fgTie("/controls/aileron-trim", this,
122 &FGControls::get_aileron_trim, &FGControls::set_aileron_trim);
123 fgSetArchivable("/controls/aileron-trim");
124 fgTie("/controls/elevator", this,
125 &FGControls::get_elevator, &FGControls::set_elevator);
126 fgSetArchivable("/controls/elevator");
127 fgTie("/controls/elevator-trim", this,
128 &FGControls::get_elevator_trim, &FGControls::set_elevator_trim);
129 fgSetArchivable("/controls/elevator-trim");
130 fgTie("/controls/rudder", this,
131 &FGControls::get_rudder, &FGControls::set_rudder);
132 fgSetArchivable("/controls/rudder");
133 fgTie("/controls/rudder-trim", this,
134 &FGControls::get_rudder_trim, &FGControls::set_rudder_trim);
135 fgSetArchivable("/controls/rudder-trim");
136 fgTie("/controls/flaps", this,
137 &FGControls::get_flaps, &FGControls::set_flaps);
138 fgSetArchivable("/controls/flaps");
140 for (index = 0; index < MAX_ENGINES; index++) {
142 sprintf(name, "/controls/throttle[%d]", index);
143 fgTie(name, this, index,
144 &FGControls::get_throttle, &FGControls::set_throttle);
145 fgSetArchivable(name);
146 sprintf(name, "/controls/mixture[%d]", index);
147 fgTie(name, this, index,
148 &FGControls::get_mixture, &FGControls::set_mixture);
149 fgSetArchivable(name);
150 sprintf(name, "/controls/fuel-pump[%d]", index);
151 fgTie(name, this, index,
152 &FGControls::get_fuel_pump, &FGControls::set_fuel_pump);
153 fgSetArchivable(name);
154 sprintf(name, "/controls/propeller-pitch[%d]", index);
155 fgTie(name, this, index,
156 &FGControls::get_prop_advance, &FGControls::set_prop_advance);
157 fgSetArchivable(name);
158 sprintf(name, "/controls/magnetos[%d]", index);
159 fgTie(name, this, index,
160 &FGControls::get_magnetos, &FGControls::set_magnetos);
161 fgSetArchivable(name);
162 sprintf(name, "/controls/starter[%d]", index);
163 fgTie(name, this, index,
164 &FGControls::get_starter, &FGControls::set_starter);
165 fgSetArchivable(name);
167 fgTie("/controls/parking-brake", this,
168 &FGControls::get_parking_brake, &FGControls::set_parking_brake);
169 fgSetArchivable("/controls/speed-brake");
170 fgTie("/controls/speed-brake", this,
171 &FGControls::get_speed_brake, &FGControls::set_speed_brake);
172 fgSetArchivable("/controls/speed-brake");
173 fgTie("/controls/spoilers", this,
174 &FGControls::get_spoilers, &FGControls::set_spoilers);
175 fgSetArchivable("/controls/spoilers");
176 for (index = 0; index < MAX_WHEELS; index++) {
178 sprintf(name, "/controls/brakes[%d]", index);
179 fgTie(name, this, index,
180 &FGControls::get_brake, &FGControls::set_brake);
181 fgSetArchivable(name);
183 for (index = 0; index < MAX_TANKS; index++) {
185 sprintf(name, "/controls/fuel-selector[%d]", index);
186 fgTie(name, this, index,
187 &FGControls::get_fuel_selector, &FGControls::set_fuel_selector);
188 fgSetArchivable(name);
190 fgTie("/controls/gear-down", this,
191 &FGControls::get_gear_down, &FGControls::set_gear_down);
192 fgSetArchivable("/controls/gear-down");
197 FGControls::unbind ()
199 // Tie control properties.
200 fgUntie("/controls/aileron");
201 fgUntie("/controls/aileron-trim");
202 fgUntie("/controls/elevator");
203 fgUntie("/controls/elevator-trim");
204 fgUntie("/controls/rudder");
205 fgUntie("/controls/rudder-trim");
206 fgUntie("/controls/flaps");
208 for (index = 0; index < MAX_ENGINES; index++) {
210 sprintf(name, "/controls/throttle[%d]", index);
212 sprintf(name, "/controls/mixture[%d]", index);
214 sprintf(name, "/controls/fuel-pump[%d]", index);
216 sprintf(name, "/controls/propeller-pitch[%d]", index);
218 sprintf(name, "/controls/magnetos[%d]", index);
220 sprintf(name, "/controls/starter[%d]", index);
223 for (index = 0; index < MAX_WHEELS; index++) {
225 sprintf(name, "/controls/brakes[%d]", index);
228 fgUntie("/controls/fuel-selector");
229 fgUntie("/controls/gear-down");
234 FGControls::update (double dt)
240 ////////////////////////////////////////////////////////////////////////
241 // Setters and adjusters.
242 ////////////////////////////////////////////////////////////////////////
245 FGControls::set_aileron (double pos)
248 CLAMP( &aileron, -1.0, 1.0 );
250 // check for autocoordination
251 if ( auto_coordination->getBoolValue() ) {
252 set_rudder( aileron / 2.0 );
257 FGControls::move_aileron (double amt)
260 CLAMP( &aileron, -1.0, 1.0 );
262 // check for autocoordination
263 if ( auto_coordination->getBoolValue() ) {
264 set_rudder( aileron / 2.0 );
269 FGControls::set_aileron_trim( double pos )
272 CLAMP( &aileron_trim, -1.0, 1.0 );
276 FGControls::move_aileron_trim( double amt )
279 CLAMP( &aileron_trim, -1.0, 1.0 );
283 FGControls::set_elevator( double pos )
286 CLAMP( &elevator, -1.0, 1.0 );
290 FGControls::move_elevator( double amt )
293 CLAMP( &elevator, -1.0, 1.0 );
297 FGControls::set_elevator_trim( double pos )
300 CLAMP( &elevator_trim, -1.0, 1.0 );
304 FGControls::move_elevator_trim( double amt )
306 elevator_trim += amt;
307 CLAMP( &elevator_trim, -1.0, 1.0 );
311 FGControls::set_rudder( double pos )
314 CLAMP( &rudder, -1.0, 1.0 );
318 FGControls::move_rudder( double amt )
321 CLAMP( &rudder, -1.0, 1.0 );
325 FGControls::set_rudder_trim( double pos )
328 CLAMP( &rudder_trim, -1.0, 1.0 );
332 FGControls::move_rudder_trim( double amt )
335 CLAMP( &rudder_trim, -1.0, 1.0 );
339 FGControls::set_flaps( double pos )
342 CLAMP( &flaps, 0.0, 1.0 );
346 FGControls::move_flaps( double amt )
349 CLAMP( &flaps, 0.0, 1.0 );
353 FGControls::set_throttle( int engine, double pos )
355 if ( engine == ALL_ENGINES ) {
356 for ( int i = 0; i < MAX_ENGINES; i++ ) {
358 CLAMP( &throttle[i], 0.0, 1.0 );
361 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
362 throttle[engine] = pos;
363 CLAMP( &throttle[engine], 0.0, 1.0 );
369 FGControls::move_throttle( int engine, double amt )
371 if ( engine == ALL_ENGINES ) {
372 for ( int i = 0; i < MAX_ENGINES; i++ ) {
374 CLAMP( &throttle[i], 0.0, 1.0 );
377 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
378 throttle[engine] += amt;
379 CLAMP( &throttle[engine], 0.0, 1.0 );
385 FGControls::set_mixture( int engine, double pos )
387 if ( engine == ALL_ENGINES ) {
388 for ( int i = 0; i < MAX_ENGINES; i++ ) {
390 CLAMP( &mixture[i], 0.0, 1.0 );
393 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
394 mixture[engine] = pos;
395 CLAMP( &mixture[engine], 0.0, 1.0 );
401 FGControls::move_mixture( int engine, double amt )
403 if ( engine == ALL_ENGINES ) {
404 for ( int i = 0; i < MAX_ENGINES; i++ ) {
406 CLAMP( &mixture[i], 0.0, 1.0 );
409 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
410 mixture[engine] += amt;
411 CLAMP( &mixture[engine], 0.0, 1.0 );
417 FGControls::set_fuel_pump( int engine, bool val )
419 if ( engine == ALL_ENGINES ) {
420 for ( int i = 0; i < MAX_ENGINES; i++ ) {
424 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
425 fuel_pump[engine] = val;
431 FGControls::set_prop_advance( int engine, double pos )
433 if ( engine == ALL_ENGINES ) {
434 for ( int i = 0; i < MAX_ENGINES; i++ ) {
435 prop_advance[i] = pos;
436 CLAMP( &prop_advance[i], 0.0, 1.0 );
439 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
440 prop_advance[engine] = pos;
441 CLAMP( &prop_advance[engine], 0.0, 1.0 );
447 FGControls::move_prop_advance( int engine, double amt )
449 if ( engine == ALL_ENGINES ) {
450 for ( int i = 0; i < MAX_ENGINES; i++ ) {
451 prop_advance[i] += amt;
452 CLAMP( &prop_advance[i], 0.0, 1.0 );
455 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
456 prop_advance[engine] += amt;
457 CLAMP( &prop_advance[engine], 0.0, 1.0 );
463 FGControls::set_magnetos( int engine, int pos )
465 if ( engine == ALL_ENGINES ) {
466 for ( int i = 0; i < MAX_ENGINES; i++ ) {
468 CLAMP( &magnetos[i], 0, 3 );
471 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
472 magnetos[engine] = pos;
473 CLAMP( &magnetos[engine], 0, 3 );
479 FGControls::move_magnetos( int engine, int amt )
481 if ( engine == ALL_ENGINES ) {
482 for ( int i = 0; i < MAX_ENGINES; i++ ) {
484 CLAMP( &magnetos[i], 0, 3 );
487 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
488 magnetos[engine] += amt;
489 CLAMP( &magnetos[engine], 0, 3 );
495 FGControls::set_starter( int engine, bool flag )
497 if ( engine == ALL_ENGINES ) {
498 for ( int i = 0; i < MAX_ENGINES; i++ ) {
502 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
503 starter[engine] = flag;
509 FGControls::set_fuel_selector( int tank, bool pos )
511 if ( tank == ALL_TANKS ) {
512 for ( int i = 0; i < MAX_TANKS; i++ ) {
513 fuel_selector[i] = pos;
516 if ( (tank >= 0) && (tank < MAX_TANKS) ) {
517 fuel_selector[tank] = pos;
524 FGControls::set_parking_brake( double pos )
527 CLAMP(&parking_brake, 0.0, 1.0);
531 FGControls::set_speed_brake( double pos )
534 CLAMP(&speed_brake, 0.0, 1.0);
538 FGControls::set_spoilers( double pos )
541 CLAMP(&spoilers, 0.0, 1.0);
545 FGControls::set_brake( int wheel, double pos )
547 if ( wheel == ALL_WHEELS ) {
548 for ( int i = 0; i < MAX_WHEELS; i++ ) {
550 CLAMP( &brake[i], 0.0, 1.0 );
553 if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
555 CLAMP( &brake[wheel], 0.0, 1.0 );
561 FGControls::move_brake( int wheel, double amt )
563 if ( wheel == ALL_WHEELS ) {
564 for ( int i = 0; i < MAX_WHEELS; i++ ) {
566 CLAMP( &brake[i], 0.0, 1.0 );
569 if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
571 CLAMP( &brake[wheel], 0.0, 1.0 );
577 FGControls::set_gear_down( bool gear )