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++ ) {
103 auto_coordination = fgGetNode("/sim/auto-coordination", true);
110 fgTie("/controls/aileron", this,
111 &FGControls::get_aileron, &FGControls::set_aileron);
112 fgSetArchivable("/controls/aileron");
113 fgTie("/controls/aileron-trim", this,
114 &FGControls::get_aileron_trim, &FGControls::set_aileron_trim);
115 fgSetArchivable("/controls/aileron-trim");
116 fgTie("/controls/elevator", this,
117 &FGControls::get_elevator, &FGControls::set_elevator);
118 fgSetArchivable("/controls/elevator");
119 fgTie("/controls/elevator-trim", this,
120 &FGControls::get_elevator_trim, &FGControls::set_elevator_trim);
121 fgSetArchivable("/controls/elevator-trim");
122 fgTie("/controls/rudder", this,
123 &FGControls::get_rudder, &FGControls::set_rudder);
124 fgSetArchivable("/controls/rudder");
125 fgTie("/controls/rudder-trim", this,
126 &FGControls::get_rudder_trim, &FGControls::set_rudder_trim);
127 fgSetArchivable("/controls/rudder-trim");
128 fgTie("/controls/flaps", this,
129 &FGControls::get_flaps, &FGControls::set_flaps);
130 fgSetArchivable("/controls/flaps");
132 for (index = 0; index < MAX_ENGINES; index++) {
134 sprintf(name, "/controls/throttle[%d]", index);
135 fgTie(name, this, index,
136 &FGControls::get_throttle, &FGControls::set_throttle);
137 fgSetArchivable(name);
138 sprintf(name, "/controls/mixture[%d]", index);
139 fgTie(name, this, index,
140 &FGControls::get_mixture, &FGControls::set_mixture);
141 fgSetArchivable(name);
142 sprintf(name, "/controls/propeller-pitch[%d]", index);
143 fgTie(name, this, index,
144 &FGControls::get_prop_advance, &FGControls::set_prop_advance);
145 fgSetArchivable(name);
146 sprintf(name, "/controls/magnetos[%d]", index);
147 fgTie(name, this, index,
148 &FGControls::get_magnetos, &FGControls::set_magnetos);
149 fgSetArchivable(name);
150 sprintf(name, "/controls/starter[%d]", index);
151 fgTie(name, this, index,
152 &FGControls::get_starter, &FGControls::set_starter);
153 fgSetArchivable(name);
155 fgTie("/controls/parking-brake", this,
156 &FGControls::get_parking_brake, &FGControls::set_parking_brake);
157 fgSetArchivable("/controls/parking-brake");
158 for (index = 0; index < MAX_WHEELS; index++) {
160 sprintf(name, "/controls/brakes[%d]", index);
161 fgTie(name, this, index,
162 &FGControls::get_brake, &FGControls::set_brake);
163 fgSetArchivable(name);
165 fgTie("/controls/gear-down", this,
166 &FGControls::get_gear_down, &FGControls::set_gear_down);
167 fgSetArchivable("/controls/gear-down");
172 FGControls::unbind ()
174 // Tie control properties.
175 fgUntie("/controls/aileron");
176 fgUntie("/controls/aileron-trim");
177 fgUntie("/controls/elevator");
178 fgUntie("/controls/elevator-trim");
179 fgUntie("/controls/rudder");
180 fgUntie("/controls/rudder-trim");
181 fgUntie("/controls/flaps");
183 for (index = 0; index < MAX_ENGINES; index++) {
185 sprintf(name, "/controls/throttle[%d]", index);
187 sprintf(name, "/controls/mixture[%d]", index);
189 sprintf(name, "/controls/propeller-pitch[%d]", index);
191 sprintf(name, "/controls/magnetos[%d]", index);
193 sprintf(name, "/controls/starter[%d]", index);
196 for (index = 0; index < MAX_WHEELS; index++) {
198 sprintf(name, "/controls/brakes[%d]", index);
201 fgUntie("/controls/gear-down");
206 FGControls::update (int dt)
212 ////////////////////////////////////////////////////////////////////////
213 // Setters and adjusters.
214 ////////////////////////////////////////////////////////////////////////
217 FGControls::set_aileron (double pos)
220 CLAMP( &aileron, -1.0, 1.0 );
222 // check for autocoordination
223 if ( auto_coordination->getBoolValue() ) {
224 set_rudder( aileron / 2.0 );
229 FGControls::move_aileron (double amt)
232 CLAMP( &aileron, -1.0, 1.0 );
234 // check for autocoordination
235 if ( auto_coordination->getBoolValue() ) {
236 set_rudder( aileron / 2.0 );
241 FGControls::set_aileron_trim( double pos )
244 CLAMP( &aileron_trim, -1.0, 1.0 );
248 FGControls::move_aileron_trim( double amt )
251 CLAMP( &aileron_trim, -1.0, 1.0 );
255 FGControls::set_elevator( double pos )
258 CLAMP( &elevator, -1.0, 1.0 );
262 FGControls::move_elevator( double amt )
265 CLAMP( &elevator, -1.0, 1.0 );
269 FGControls::set_elevator_trim( double pos )
272 CLAMP( &elevator_trim, -1.0, 1.0 );
276 FGControls::move_elevator_trim( double amt )
278 elevator_trim += amt;
279 CLAMP( &elevator_trim, -1.0, 1.0 );
283 FGControls::set_rudder( double pos )
286 CLAMP( &rudder, -1.0, 1.0 );
290 FGControls::move_rudder( double amt )
293 CLAMP( &rudder, -1.0, 1.0 );
297 FGControls::set_rudder_trim( double pos )
300 CLAMP( &rudder_trim, -1.0, 1.0 );
304 FGControls::move_rudder_trim( double amt )
307 CLAMP( &rudder_trim, -1.0, 1.0 );
311 FGControls::set_flaps( double pos )
314 CLAMP( &flaps, 0.0, 1.0 );
318 FGControls::move_flaps( double amt )
321 CLAMP( &flaps, 0.0, 1.0 );
325 FGControls::set_throttle( int engine, double pos )
327 if ( engine == ALL_ENGINES ) {
328 for ( int i = 0; i < MAX_ENGINES; i++ ) {
330 CLAMP( &throttle[i], 0.0, 1.0 );
333 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
334 throttle[engine] = pos;
335 CLAMP( &throttle[engine], 0.0, 1.0 );
341 FGControls::move_throttle( int engine, double amt )
343 if ( engine == ALL_ENGINES ) {
344 for ( int i = 0; i < MAX_ENGINES; i++ ) {
346 CLAMP( &throttle[i], 0.0, 1.0 );
349 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
350 throttle[engine] += amt;
351 CLAMP( &throttle[engine], 0.0, 1.0 );
357 FGControls::set_mixture( int engine, double pos )
359 if ( engine == ALL_ENGINES ) {
360 for ( int i = 0; i < MAX_ENGINES; i++ ) {
362 CLAMP( &mixture[i], 0.0, 1.0 );
365 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
366 mixture[engine] = pos;
367 CLAMP( &mixture[engine], 0.0, 1.0 );
373 FGControls::move_mixture( int engine, double amt )
375 if ( engine == ALL_ENGINES ) {
376 for ( int i = 0; i < MAX_ENGINES; i++ ) {
378 CLAMP( &mixture[i], 0.0, 1.0 );
381 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
382 mixture[engine] += amt;
383 CLAMP( &mixture[engine], 0.0, 1.0 );
389 FGControls::set_prop_advance( int engine, double pos )
391 if ( engine == ALL_ENGINES ) {
392 for ( int i = 0; i < MAX_ENGINES; i++ ) {
393 prop_advance[i] = pos;
394 CLAMP( &prop_advance[i], 0.0, 1.0 );
397 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
398 prop_advance[engine] = pos;
399 CLAMP( &prop_advance[engine], 0.0, 1.0 );
405 FGControls::move_prop_advance( int engine, double amt )
407 if ( engine == ALL_ENGINES ) {
408 for ( int i = 0; i < MAX_ENGINES; i++ ) {
409 prop_advance[i] += amt;
410 CLAMP( &prop_advance[i], 0.0, 1.0 );
413 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
414 prop_advance[engine] += amt;
415 CLAMP( &prop_advance[engine], 0.0, 1.0 );
421 FGControls::set_magnetos( int engine, int pos )
423 if ( engine == ALL_ENGINES ) {
424 for ( int i = 0; i < MAX_ENGINES; i++ ) {
426 CLAMP( &magnetos[i], 0, 3 );
429 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
430 magnetos[engine] = pos;
431 CLAMP( &magnetos[engine], 0, 3 );
437 FGControls::move_magnetos( int engine, int amt )
439 if ( engine == ALL_ENGINES ) {
440 for ( int i = 0; i < MAX_ENGINES; i++ ) {
442 CLAMP( &magnetos[i], 0, 3 );
445 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
446 magnetos[engine] += amt;
447 CLAMP( &magnetos[engine], 0, 3 );
453 FGControls::set_starter( int engine, bool flag )
455 if ( engine == ALL_ENGINES ) {
456 for ( int i = 0; i < MAX_ENGINES; i++ ) {
460 if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
461 starter[engine] = flag;
467 FGControls::set_parking_brake( double pos )
470 CLAMP(&parking_brake, 0.0, 1.0);
474 FGControls::set_brake( int wheel, double pos )
476 if ( wheel == ALL_WHEELS ) {
477 for ( int i = 0; i < MAX_WHEELS; i++ ) {
479 CLAMP( &brake[i], 0.0, 1.0 );
482 if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
484 CLAMP( &brake[wheel], 0.0, 1.0 );
490 FGControls::move_brake( int wheel, double amt )
492 if ( wheel == ALL_WHEELS ) {
493 for ( int i = 0; i < MAX_WHEELS; i++ ) {
495 CLAMP( &brake[i], 0.0, 1.0 );
498 if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
500 CLAMP( &brake[wheel], 0.0, 1.0 );
506 FGControls::set_gear_down( bool gear )