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() :
67 void FGControls::reset_all()
70 set_aileron_trim(0.0);
72 set_elevator_trim(0.0);
75 set_throttle(FGControls::ALL_ENGINES, 0.0);
76 set_starter(FGControls::ALL_ENGINES, false);
77 set_magnetos(FGControls::ALL_ENGINES, 0);
84 FGControls::~FGControls() {
91 for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
92 throttle[engine] = 0.0;
93 mixture[engine] = 1.0;
94 prop_advance[engine] = 1.0;
96 starter[engine] = false;
99 for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
104 auto_coordination = fgGetNode("/sim/auto-coordination", true);
111 fgTie("/controls/aileron", this,
112 &FGControls::get_aileron, &FGControls::set_aileron);
113 fgSetArchivable("/controls/aileron");
114 fgTie("/controls/aileron-trim", this,
115 &FGControls::get_aileron_trim, &FGControls::set_aileron_trim);
116 fgSetArchivable("/controls/aileron-trim");
117 fgTie("/controls/elevator", this,
118 &FGControls::get_elevator, &FGControls::set_elevator);
119 fgSetArchivable("/controls/elevator");
120 fgTie("/controls/elevator-trim", this,
121 &FGControls::get_elevator_trim, &FGControls::set_elevator_trim);
122 fgSetArchivable("/controls/elevator-trim");
123 fgTie("/controls/rudder", this,
124 &FGControls::get_rudder, &FGControls::set_rudder);
125 fgSetArchivable("/controls/rudder");
126 fgTie("/controls/rudder-trim", this,
127 &FGControls::get_rudder_trim, &FGControls::set_rudder_trim);
128 fgSetArchivable("/controls/rudder-trim");
129 fgTie("/controls/flaps", this,
130 &FGControls::get_flaps, &FGControls::set_flaps);
131 fgSetArchivable("/controls/flaps");
133 for (index = 0; index < MAX_ENGINES; index++) {
135 sprintf(name, "/controls/throttle[%d]", index);
136 fgTie(name, this, index,
137 &FGControls::get_throttle, &FGControls::set_throttle);
138 fgSetArchivable(name);
139 sprintf(name, "/controls/mixture[%d]", index);
140 fgTie(name, this, index,
141 &FGControls::get_mixture, &FGControls::set_mixture);
142 fgSetArchivable(name);
143 sprintf(name, "/controls/propeller-pitch[%d]", index);
144 fgTie(name, this, index,
145 &FGControls::get_prop_advance, &FGControls::set_prop_advance);
146 fgSetArchivable(name);
147 sprintf(name, "/controls/magnetos[%d]", index);
148 fgTie(name, this, index,
149 &FGControls::get_magnetos, &FGControls::set_magnetos);
150 fgSetArchivable(name);
151 sprintf(name, "/controls/starter[%d]", index);
152 fgTie(name, this, index,
153 &FGControls::get_starter, &FGControls::set_starter);
154 fgSetArchivable(name);
156 fgTie("/controls/parking-brake", this,
157 &FGControls::get_parking_brake, &FGControls::set_parking_brake);
158 fgSetArchivable("/controls/parking-brake");
159 for (index = 0; index < MAX_WHEELS; index++) {
161 sprintf(name, "/controls/brakes[%d]", index);
162 fgTie(name, this, index,
163 &FGControls::get_brake, &FGControls::set_brake);
164 fgSetArchivable(name);
166 fgTie("/controls/gear-down", this,
167 &FGControls::get_gear_down, &FGControls::set_gear_down);
168 fgSetArchivable("/controls/gear-down");
173 FGControls::unbind ()
175 // Tie control properties.
176 fgUntie("/controls/aileron");
177 fgUntie("/controls/aileron-trim");
178 fgUntie("/controls/elevator");
179 fgUntie("/controls/elevator-trim");
180 fgUntie("/controls/rudder");
181 fgUntie("/controls/rudder-trim");
182 fgUntie("/controls/flaps");
184 for (index = 0; index < MAX_ENGINES; index++) {
186 sprintf(name, "/controls/throttle[%d]", index);
188 sprintf(name, "/controls/mixture[%d]", index);
190 sprintf(name, "/controls/propeller-pitch[%d]", index);
192 sprintf(name, "/controls/magnetos[%d]", index);
194 sprintf(name, "/controls/starter[%d]", index);
197 for (index = 0; index < MAX_WHEELS; index++) {
199 sprintf(name, "/controls/brakes[%d]", index);
202 fgUntie("/controls/gear-down");
207 FGControls::update (int dt)
213 ////////////////////////////////////////////////////////////////////////
214 // Setters and adjusters.
215 ////////////////////////////////////////////////////////////////////////
218 FGControls::set_aileron (double pos)
221 CLAMP( &aileron, -1.0, 1.0 );
223 // check for autocoordination
224 if ( auto_coordination->getBoolValue() ) {
225 set_rudder( aileron / 2.0 );
230 FGControls::move_aileron (double amt)
233 CLAMP( &aileron, -1.0, 1.0 );
235 // check for autocoordination
236 if ( auto_coordination->getBoolValue() ) {
237 set_rudder( aileron / 2.0 );
242 FGControls::set_aileron_trim( double pos )
245 CLAMP( &aileron_trim, -1.0, 1.0 );
249 FGControls::move_aileron_trim( double amt )
252 CLAMP( &aileron_trim, -1.0, 1.0 );
256 FGControls::set_elevator( double pos )
259 CLAMP( &elevator, -1.0, 1.0 );
263 FGControls::move_elevator( double amt )
266 CLAMP( &elevator, -1.0, 1.0 );
270 FGControls::set_elevator_trim( double pos )
273 CLAMP( &elevator_trim, -1.0, 1.0 );
277 FGControls::move_elevator_trim( double amt )
279 elevator_trim += amt;
280 CLAMP( &elevator_trim, -1.0, 1.0 );
284 FGControls::set_rudder( double pos )
287 CLAMP( &rudder, -1.0, 1.0 );
291 FGControls::move_rudder( double amt )
294 CLAMP( &rudder, -1.0, 1.0 );
298 FGControls::set_rudder_trim( double pos )
301 CLAMP( &rudder_trim, -1.0, 1.0 );
305 FGControls::move_rudder_trim( double amt )
308 CLAMP( &rudder_trim, -1.0, 1.0 );
312 FGControls::set_flaps( double pos )
315 CLAMP( &flaps, 0.0, 1.0 );
319 FGControls::move_flaps( double amt )
322 CLAMP( &flaps, 0.0, 1.0 );
326 FGControls::set_throttle( int engine, double pos )
328 if ( engine == ALL_ENGINES ) {
329 for ( int i = 0; i < MAX_ENGINES; i++ ) {
331 CLAMP( &throttle[i], 0.0, 1.0 );
334 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
335 throttle[engine] = pos;
336 CLAMP( &throttle[engine], 0.0, 1.0 );
342 FGControls::move_throttle( int engine, double amt )
344 if ( engine == ALL_ENGINES ) {
345 for ( int i = 0; i < MAX_ENGINES; i++ ) {
347 CLAMP( &throttle[i], 0.0, 1.0 );
350 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
351 throttle[engine] += amt;
352 CLAMP( &throttle[engine], 0.0, 1.0 );
358 FGControls::set_mixture( int engine, double pos )
360 if ( engine == ALL_ENGINES ) {
361 for ( int i = 0; i < MAX_ENGINES; i++ ) {
363 CLAMP( &mixture[i], 0.0, 1.0 );
366 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
367 mixture[engine] = pos;
368 CLAMP( &mixture[engine], 0.0, 1.0 );
374 FGControls::move_mixture( int engine, double amt )
376 if ( engine == ALL_ENGINES ) {
377 for ( int i = 0; i < MAX_ENGINES; i++ ) {
379 CLAMP( &mixture[i], 0.0, 1.0 );
382 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
383 mixture[engine] += amt;
384 CLAMP( &mixture[engine], 0.0, 1.0 );
390 FGControls::set_prop_advance( int engine, double pos )
392 if ( engine == ALL_ENGINES ) {
393 for ( int i = 0; i < MAX_ENGINES; i++ ) {
394 prop_advance[i] = pos;
395 CLAMP( &prop_advance[i], 0.0, 1.0 );
398 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
399 prop_advance[engine] = pos;
400 CLAMP( &prop_advance[engine], 0.0, 1.0 );
406 FGControls::move_prop_advance( int engine, double amt )
408 if ( engine == ALL_ENGINES ) {
409 for ( int i = 0; i < MAX_ENGINES; i++ ) {
410 prop_advance[i] += amt;
411 CLAMP( &prop_advance[i], 0.0, 1.0 );
414 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
415 prop_advance[engine] += amt;
416 CLAMP( &prop_advance[engine], 0.0, 1.0 );
422 FGControls::set_magnetos( int engine, int pos )
424 if ( engine == ALL_ENGINES ) {
425 for ( int i = 0; i < MAX_ENGINES; i++ ) {
427 CLAMP( &magnetos[i], 0, 3 );
430 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
431 magnetos[engine] = pos;
432 CLAMP( &magnetos[engine], 0, 3 );
438 FGControls::move_magnetos( int engine, int amt )
440 if ( engine == ALL_ENGINES ) {
441 for ( int i = 0; i < MAX_ENGINES; i++ ) {
443 CLAMP( &magnetos[i], 0, 3 );
446 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
447 magnetos[engine] += amt;
448 CLAMP( &magnetos[engine], 0, 3 );
454 FGControls::set_starter( int engine, bool flag )
456 if ( engine == ALL_ENGINES ) {
457 for ( int i = 0; i < MAX_ENGINES; i++ ) {
461 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
462 starter[engine] = flag;
468 FGControls::set_parking_brake( double pos )
471 CLAMP(&parking_brake, 0.0, 1.0);
475 FGControls::set_brake( int wheel, double pos )
477 if ( wheel == ALL_WHEELS ) {
478 for ( int i = 0; i < MAX_WHEELS; i++ ) {
480 CLAMP( &brake[i], 0.0, 1.0 );
483 if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
485 CLAMP( &brake[wheel], 0.0, 1.0 );
491 FGControls::move_brake( int wheel, double amt )
493 if ( wheel == ALL_WHEELS ) {
494 for ( int i = 0; i < MAX_WHEELS; i++ ) {
496 CLAMP( &brake[i], 0.0, 1.0 );
499 if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
501 CLAMP( &brake[wheel], 0.0, 1.0 );
507 FGControls::set_gear_down( bool gear )