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() :
64 throttle_idle( true ),
70 void FGControls::reset_all()
73 set_aileron_trim(0.0);
75 set_elevator_trim(0.0);
78 set_throttle(FGControls::ALL_ENGINES, 0.0);
79 set_starter(FGControls::ALL_ENGINES, false);
80 set_magnetos(FGControls::ALL_ENGINES, 0);
87 FGControls::~FGControls() {
94 for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
95 throttle[engine] = 0.0;
96 mixture[engine] = 1.0;
97 prop_advance[engine] = 1.0;
99 starter[engine] = false;
102 for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
106 auto_coordination = fgGetNode("/sim/auto-coordination", true);
113 fgTie("/controls/aileron", this,
114 &FGControls::get_aileron, &FGControls::set_aileron);
115 fgSetArchivable("/controls/aileron");
116 fgTie("/controls/aileron-trim", this,
117 &FGControls::get_aileron_trim, &FGControls::set_aileron_trim);
118 fgSetArchivable("/controls/aileron-trim");
119 fgTie("/controls/elevator", this,
120 &FGControls::get_elevator, &FGControls::set_elevator);
121 fgSetArchivable("/controls/elevator");
122 fgTie("/controls/elevator-trim", this,
123 &FGControls::get_elevator_trim, &FGControls::set_elevator_trim);
124 fgSetArchivable("/controls/elevator-trim");
125 fgTie("/controls/rudder", this,
126 &FGControls::get_rudder, &FGControls::set_rudder);
127 fgSetArchivable("/controls/rudder");
128 fgTie("/controls/rudder-trim", this,
129 &FGControls::get_rudder_trim, &FGControls::set_rudder_trim);
130 fgSetArchivable("/controls/rudder-trim");
131 fgTie("/controls/flaps", this,
132 &FGControls::get_flaps, &FGControls::set_flaps);
133 fgSetArchivable("/controls/flaps");
135 for (index = 0; index < MAX_ENGINES; index++) {
137 sprintf(name, "/controls/throttle[%d]", index);
138 fgTie(name, this, index,
139 &FGControls::get_throttle, &FGControls::set_throttle);
140 fgSetArchivable(name);
141 sprintf(name, "/controls/mixture[%d]", index);
142 fgTie(name, this, index,
143 &FGControls::get_mixture, &FGControls::set_mixture);
144 fgSetArchivable(name);
145 sprintf(name, "/controls/propeller-pitch[%d]", index);
146 fgTie(name, this, index,
147 &FGControls::get_prop_advance, &FGControls::set_prop_advance);
148 fgSetArchivable(name);
149 sprintf(name, "/controls/magnetos[%d]", index);
150 fgTie(name, this, index,
151 &FGControls::get_magnetos, &FGControls::set_magnetos);
152 fgSetArchivable(name);
153 sprintf(name, "/controls/starter[%d]", index);
154 fgTie(name, this, index,
155 &FGControls::get_starter, &FGControls::set_starter);
156 fgSetArchivable(name);
158 fgTie("/controls/parking-brake", this,
159 &FGControls::get_parking_brake, &FGControls::set_parking_brake);
160 fgSetArchivable("/controls/parking-brake");
161 for (index = 0; index < MAX_WHEELS; index++) {
163 sprintf(name, "/controls/brakes[%d]", index);
164 fgTie(name, this, index,
165 &FGControls::get_brake, &FGControls::set_brake);
166 fgSetArchivable(name);
168 fgTie("/controls/gear-down", this,
169 &FGControls::get_gear_down, &FGControls::set_gear_down);
170 fgSetArchivable("/controls/gear-down");
175 FGControls::unbind ()
177 // Tie control properties.
178 fgUntie("/controls/aileron");
179 fgUntie("/controls/aileron-trim");
180 fgUntie("/controls/elevator");
181 fgUntie("/controls/elevator-trim");
182 fgUntie("/controls/rudder");
183 fgUntie("/controls/rudder-trim");
184 fgUntie("/controls/flaps");
186 for (index = 0; index < MAX_ENGINES; index++) {
188 sprintf(name, "/controls/throttle[%d]", index);
190 sprintf(name, "/controls/mixture[%d]", index);
192 sprintf(name, "/controls/propeller-pitch[%d]", index);
194 sprintf(name, "/controls/magnetos[%d]", index);
196 sprintf(name, "/controls/starter[%d]", index);
199 for (index = 0; index < MAX_WHEELS; index++) {
201 sprintf(name, "/controls/brakes[%d]", index);
204 fgUntie("/controls/gear-down");
209 FGControls::update (double dt)
215 ////////////////////////////////////////////////////////////////////////
216 // Setters and adjusters.
217 ////////////////////////////////////////////////////////////////////////
220 FGControls::set_aileron (double pos)
223 CLAMP( &aileron, -1.0, 1.0 );
225 // check for autocoordination
226 if ( auto_coordination->getBoolValue() ) {
227 set_rudder( aileron / 2.0 );
232 FGControls::move_aileron (double amt)
235 CLAMP( &aileron, -1.0, 1.0 );
237 // check for autocoordination
238 if ( auto_coordination->getBoolValue() ) {
239 set_rudder( aileron / 2.0 );
244 FGControls::set_aileron_trim( double pos )
247 CLAMP( &aileron_trim, -1.0, 1.0 );
251 FGControls::move_aileron_trim( double amt )
254 CLAMP( &aileron_trim, -1.0, 1.0 );
258 FGControls::set_elevator( double pos )
261 CLAMP( &elevator, -1.0, 1.0 );
265 FGControls::move_elevator( double amt )
268 CLAMP( &elevator, -1.0, 1.0 );
272 FGControls::set_elevator_trim( double pos )
275 CLAMP( &elevator_trim, -1.0, 1.0 );
279 FGControls::move_elevator_trim( double amt )
281 elevator_trim += amt;
282 CLAMP( &elevator_trim, -1.0, 1.0 );
286 FGControls::set_rudder( double pos )
289 CLAMP( &rudder, -1.0, 1.0 );
293 FGControls::move_rudder( double amt )
296 CLAMP( &rudder, -1.0, 1.0 );
300 FGControls::set_rudder_trim( double pos )
303 CLAMP( &rudder_trim, -1.0, 1.0 );
307 FGControls::move_rudder_trim( double amt )
310 CLAMP( &rudder_trim, -1.0, 1.0 );
314 FGControls::set_flaps( double pos )
317 CLAMP( &flaps, 0.0, 1.0 );
321 FGControls::move_flaps( double amt )
324 CLAMP( &flaps, 0.0, 1.0 );
328 FGControls::set_throttle( int engine, double pos )
330 if ( engine == ALL_ENGINES ) {
331 for ( int i = 0; i < MAX_ENGINES; i++ ) {
333 CLAMP( &throttle[i], 0.0, 1.0 );
336 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
337 throttle[engine] = pos;
338 CLAMP( &throttle[engine], 0.0, 1.0 );
344 FGControls::move_throttle( int engine, double amt )
346 if ( engine == ALL_ENGINES ) {
347 for ( int i = 0; i < MAX_ENGINES; i++ ) {
349 CLAMP( &throttle[i], 0.0, 1.0 );
352 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
353 throttle[engine] += amt;
354 CLAMP( &throttle[engine], 0.0, 1.0 );
360 FGControls::set_mixture( int engine, double pos )
362 if ( engine == ALL_ENGINES ) {
363 for ( int i = 0; i < MAX_ENGINES; i++ ) {
365 CLAMP( &mixture[i], 0.0, 1.0 );
368 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
369 mixture[engine] = pos;
370 CLAMP( &mixture[engine], 0.0, 1.0 );
376 FGControls::move_mixture( int engine, double amt )
378 if ( engine == ALL_ENGINES ) {
379 for ( int i = 0; i < MAX_ENGINES; i++ ) {
381 CLAMP( &mixture[i], 0.0, 1.0 );
384 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
385 mixture[engine] += amt;
386 CLAMP( &mixture[engine], 0.0, 1.0 );
392 FGControls::set_prop_advance( int engine, double pos )
394 if ( engine == ALL_ENGINES ) {
395 for ( int i = 0; i < MAX_ENGINES; i++ ) {
396 prop_advance[i] = pos;
397 CLAMP( &prop_advance[i], 0.0, 1.0 );
400 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
401 prop_advance[engine] = pos;
402 CLAMP( &prop_advance[engine], 0.0, 1.0 );
408 FGControls::move_prop_advance( int engine, double amt )
410 if ( engine == ALL_ENGINES ) {
411 for ( int i = 0; i < MAX_ENGINES; i++ ) {
412 prop_advance[i] += amt;
413 CLAMP( &prop_advance[i], 0.0, 1.0 );
416 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
417 prop_advance[engine] += amt;
418 CLAMP( &prop_advance[engine], 0.0, 1.0 );
424 FGControls::set_magnetos( int engine, int pos )
426 if ( engine == ALL_ENGINES ) {
427 for ( int i = 0; i < MAX_ENGINES; i++ ) {
429 CLAMP( &magnetos[i], 0, 3 );
432 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
433 magnetos[engine] = pos;
434 CLAMP( &magnetos[engine], 0, 3 );
440 FGControls::move_magnetos( int engine, int amt )
442 if ( engine == ALL_ENGINES ) {
443 for ( int i = 0; i < MAX_ENGINES; i++ ) {
445 CLAMP( &magnetos[i], 0, 3 );
448 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
449 magnetos[engine] += amt;
450 CLAMP( &magnetos[engine], 0, 3 );
456 FGControls::set_starter( int engine, bool flag )
458 if ( engine == ALL_ENGINES ) {
459 for ( int i = 0; i < MAX_ENGINES; i++ ) {
463 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
464 starter[engine] = flag;
470 FGControls::set_parking_brake( double pos )
473 CLAMP(&parking_brake, 0.0, 1.0);
477 FGControls::set_brake( int wheel, double pos )
479 if ( wheel == ALL_WHEELS ) {
480 for ( int i = 0; i < MAX_WHEELS; i++ ) {
482 CLAMP( &brake[i], 0.0, 1.0 );
485 if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
487 CLAMP( &brake[wheel], 0.0, 1.0 );
493 FGControls::move_brake( int wheel, double amt )
495 if ( wheel == ALL_WHEELS ) {
496 for ( int i = 0; i < MAX_WHEELS; i++ ) {
498 CLAMP( &brake[i], 0.0, 1.0 );
501 if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
503 CLAMP( &brake[wheel], 0.0, 1.0 );
509 FGControls::set_gear_down( bool gear )