Remove old references to /sim/auto-coordination.
[fg:toms-fgdata.git] / Input / Joysticks / Saitek / X52.xml
1 <?xml version="1.0"?>
2 <!--
3
4 This is X52.xml, the joystick config file for the Saitek X52 
5 USB stick and throttle.
6
7 This configuration is meant to be suitable for a generic single-engine
8 aircraft.
9
10 Here are some of the features of a real aircraft that we would like to
11 implement, and our "preferred" way of assigning them on the X52.
12
13   Flight Controls:
14     Aileron             stick L/R
15     Elevator            stick fwd/aft
16     Rudder              stick twist (or pedals!)
17     Flaps               T3/T4
18     Speedbrakes         shift T3/T4
19     Pitch trim          stick upper hat
20     Rudder trim         stick upper hat
21     Aileron trim        throttle rocker
22   Engine controls:
23     Throttle            throttle
24     Mixture             throttle lower rotary
25     Propeller RPM       throttle thumb slider
26     Carb heat (alt air) T5/T6
27     Cowl Flaps          shift T5/T6
28     Fuel tank select    **not implemented**
29     Mag switch          keyboard "{" and "}"
30     Starter             keyboard "s"
31   Other important stuff:
32     gear handle up/down T1/T2
33     Overall brakes      pinky trigger
34     L/R toe brakes      keyboard dot and comma
35     Parking brakes      keyboard capital-B
36     Push-to-talk        button (A) is a good candidate
37                         also keyboard "space"
38     Timer reset         MultiFunc reset
39     Timer -> clock      MultiFunc function
40     Autopilot disengage **not implemented**
41     Autopilot go-around **not implemented**
42   Electrical:
43     Master              **not implemented**
44     Radio master        **not implemented**
45     Landing lights      **not implemented**
46     Rotating beacon     **not implemented**
47     Strobes             **not implemented**
48     Cabin lights        **not implemented**
49     Instrument lights   **not implemented**
50     Circuit breakers    **not implemented**
51   Instruments:
52     Alternate static    **not implemented**
53     Instruments on/off  mouse
54     Instruments tuning  mouse or popup dialog
55   Simulator and view control:
56     Pan L/R Tilt Up/Dn  throttle lower hat
57     Shift PoV           D-shift + throttle lower hat
58     Restore std view    (C) button
59     Zoom out            (B) button
60     Zoom in             D-shift + (B) button
61
62 =============================================================
63
64 Here are the Unix axes observed by jsd using js_demo, and Windows axes
65 observed by Satia Lumbar. Mac axes are little more than guesses based
66 on reports of X45 behavior.  An "x" means observed to have no effect
67 using js_demo.  U/M/W means unix/mac/windows:
68
69    U/ M/ W  Hardware Function             Interpretation
70    =======  =================             ==============
71    0/ 0/ 0  Stick yaw             +=R     Aileron
72    1/ 1/ 1  Stick pitch           +=aft   Elevator
73    2/ 2/ 2  Throttle              +=aft   Throttle
74    3/ 5/ 5  Throttle lower rotary +=cw    Mixture (fwd = rich)
75    4/ 8/ 8x Throttle upper rotary +=cw    [unassigned]
76    5/ 3/ 3  Stick twist           +=R     Rudder
77    6/ 4/ 4  Throttle thumb slider +=up    Prop (fwd = high RPM)
78    7/ 6/ 6  Stick lower hat       +=R     Pan View Left/Right ... or shift
79    8/ 7/ 7  Stick lower hat       +=down  Tilt View Up/Down ... or shift
80    9/ 9/ 9x Green mouse           +=up    [Mouse???]
81   10/10/10x Green mouse           +=away  [Mouse???]
82
83
84 On the Windows platform, the assignment of axes 8, 9, and 10 as
85 given above is only a hint, suggesting how the axes /should/ be
86 assigned, if the lower-level implementation ever gets around to
87 assigning them.
88
89 In the meantime, I have maintained cross-platform compatibility by not
90 assigning any critical functions to axes that don't work on the
91 Windows platform.
92
93 =======================
94
95 Now for the buttons.  Unix button numbers observed by jsd using
96 js_demo.  (Others rumored to be identical on Unix/Mac/Windows.)
97
98 Before 1 Jan 2007, all versions of plib had a bug that affecting bits
99 32 and 33.  The C and C++ language spec says that an out-of-range
100 shift (such as shifting a 32-bit word 32 or more places) produces an
101 /undefined/ result.  It is really not a good practice to be generating
102 undefined results.
103
104 I observe that on /some/ systems, bit #32 creates a conflict with bit
105 #0, and bit #33 creates a conflict with bit #1.  That is, they "wrap
106 around" the word boundary.  This means that if you roll the gray trim
107 wheel, it fires the gun!  If that weren't bad enough, this behavior is
108 not guaranteed from compiler to compiler or from hardware to hardware.
109 Remember, according to the C language spec, an out-of-range shift
110 produces an "undefined" result, so implementers can do anything they
111 want with it.
112
113
114 Bit  Binary     Hardware Function       Interpretation
115 ===  =========  =================       ====================
116  0 = 0000 0001  Trigger (see also #14)
117  0' (see also #32)
118  1 = 0000 0002  FIRE Button (guarded)
119  1' (see also #33)
120  2 = 0000 0004  (A) Button              (should be push-to-talk)
121  3 = 0000 0008  (B) Button              Expand field of view (shift: contract)
122  4 = 0000 0010  (C) Button              Reset View
123  5 = 0000 0020  Pinky subtrigger        Apply brakes
124  6 = 0000 0040  (D) Button              D-Shift, modifies other functions
125  7 = 0000 0080  (E) Button
126  8 = 0000 0100  T1                      Gear Handle Up
127  9 = 0000 0200  T2                      Gear Handle Down
128 10 = 0000 0400  T3                      Flaps retract 1 notch  (shift: speed brakes extend)
129 11 = 0000 0800  T4                      Flaps extend  1 notch  (shift: speed brakes retract)
130 12 = 0000 1000  T5                      Carb heat on  (shift: cowl flaps close)
131 13 = 0000 2000  T6                      Carb heat off (shift: cowl flaps open)
132 14 = 0000 4001  More Trigger (==> #0)
133 15 = 0000 8000  Yoke upper hat Fwd      Elevator trim
134 16 = 0001 0000  Yoke upper hat R        Rudder trim
135 17 = 0002 0000  Yoke upper hat Aft      Elevator trim
136 18 = 0004 0000  Yoke upper hat L        Rudder trim
137 19 = 0008 0000  Throttle rocker aft
138 20 = 0010 0000  Throttle rocker R       Aileron trim
139 21 = 0020 0000  Throttle rocker fwd
140 22 = 0040 0000  Throttle rocker L       Aileron trim
141 23 = 0080 0000  Mode Aft (green)
142 24 = 0100 0000  Mode Mid (pink)
143 25 = 0200 0000  Mode Fwd (red)
144 26 = 0400 0000  MultiFunc Function      Timer -> clock again
145 27 = 0800 0000  MultiFunc Start/Stop    ** Timer start/stop not implemented **
146 28 = 1000 0000  MultiFunc Reset         Timer reset
147 29 = 2000 0000  (i) Button
148 30 = 4000 0000  Green mouse click
149 31 (not observed)
150 32 = 1 0000 0000  Gray Roller step fwd  (see also bit #0)
151 33 = 2 0000 0000  Gray Roller step aft  (see also bit #1)
152
153 == Notes:
154
155 *) Note that some joystick configurations specify square-law behavior
156  for some flight control axes (e.g. ailerons and/or rudder).  This is
157  very unlike the behavior of flight controls on real aircraft.
158
159  Aileron authority should be mushy at low airspeeds and crisp at high
160  airspeeds ... but this should be part of the flight dynamics of the
161  aircraft.  Building the correct behavior into the control stick
162  configuration is neither possible nor desirable.
163
164
165 *) There are some aircraft in the simulator fleet that have very
166  little roll damping and very little yaw damping.  (You could also say
167  they have very little damping of the Dutch roll mode, but this is
168  merely a natural consequence of the roll and yaw issues, not really a
169  separate issue.)
170
171  Such aircraft are vastly easier to fly with auto-coordination turned
172  on.  In my opinion, you want auto-coordination on for flying an ILS
173  partial panel, i.e. no DG and no AI.  
174  
175  For a crosswind landing, you need to have auto-coordination turned off.
176  That's why the switch to do that is on the yoke.
177
178 *) This configuration does not bind the parking brake to any button on
179  the joystick (or throttle).  Using the keyboard (shift-B) seems
180  entirely satisfactory and more realistic than putting the /parking/
181  brake button on the stick.  
182
183 *) In general, he HOTAS idea (hands on throttle and stick) should
184  apply to things you need /in flight/.
185
186 -->
187
188 <PropertyList>
189  
190  <name>Saitek X52</name>
191  <name>Saitek X52 Flight Controller USB</name>
192  <name>Saitek X52 Flight Controller</name>
193  <name>Saitek X52 Flight Control Stick </name>
194  <name>Saitek X52 Flight Stick (USB)</name>
195  <name>Saitek X52 Flight Control System</name>
196  <name>Saitek Saitek X52</name>
197  <name>Saitek Saitek X52 Flight Stick (USB)</name>
198  <name>Saitek Saitek X52 Flight Control Stick</name>
199  <name>Saitek Saitek X52 Flight Control System</name>
200
201 <axis>  <!-- 0/0/0 -->
202   <desc>Aileron</desc>
203   <number>
204    <unix>0</unix>
205    <mac>0</mac>
206    <windows>0</windows>
207   </number>
208   <binding>
209    <command>property-scale</command>
210    <property>/controls/flight/aileron</property>
211   </binding>
212 </axis>
213
214 <axis>  <!-- 1/1/1 -->
215   <desc>Elevator</desc>
216   <number>
217    <unix>1</unix>
218    <mac>1</mac>
219    <windows>1</windows>
220   </number>
221   <binding>
222    <command>property-scale</command>
223    <property>/controls/flight/elevator</property>
224    <factor type="double">-1.0</factor>
225   </binding>
226 </axis>
227
228 <axis>  <!-- 2/2/2 -->
229   <desc>Throttle</desc>
230   <number>
231    <unix>2</unix>
232    <mac>2</mac>
233    <windows>2</windows>
234   </number>
235   <binding>
236    <command>nasal</command>
237    <script>controls.throttleAxis()</script>
238   </binding>
239 </axis>
240
241 <axis>  <!-- 3/5/5 -->
242   <desc>Mixture</desc>
243   <number>
244    <unix>3</unix>
245    <mac>5</mac>
246    <windows>5</windows>
247   </number>
248   <binding>
249    <command>nasal</command>
250    <script>controls.mixtureAxis(-1)</script>
251   </binding>
252 </axis>
253
254 <!-- Alternate Prop RPM :: throttle upper rotary -->
255 <axis>  <!-- 4/8/8 -->
256   <desc>unassigned (was: Propeller RPM)</desc>
257   <number>
258    <unix>4</unix>
259    <mac>8</mac>
260    <windows>8</windows>
261   </number>
262   <binding>
263    <command>nasal</command>
264    <script>
265      ####controls.propellerAxis(-1)
266    </script>
267   </binding>
268 </axis>
269
270 <!-- Rudder :: stick twist -->
271 <axis>  <!-- 5/3/3 -->
272     <desc>Rudder</desc>
273     <number>
274         <unix>5</unix>
275         <mac>3</mac>
276         <windows>3</windows>
277     </number>
278     <binding>
279         <command>property-scale</command>
280         <property>/controls/flight/rudder</property>
281     </binding>
282 </axis>
283
284 <!-- Propeller RPM :: throttle thumb slider --> 
285 <axis>  <!-- 6/4/4 -->
286   <desc>Propeller RPM</desc>
287   <number>
288    <unix>6</unix>
289    <mac>4</mac>
290    <windows>4</windows>
291   </number>
292   <binding>
293    <command>nasal</command>
294    <script>controls.propellerAxis(-1)</script>
295   </binding>
296 </axis>
297
298
299 <!-- View Direction :: stick lower hat -->
300 <axis>  <!-- 7/6/6 -->
301   <desc>View Pan Left/Right (D-shift: move PoV)</desc>
302   <number>
303    <unix>7</unix>
304    <mac>6</mac>
305    <windows>6</windows>
306   </number>
307   <low>
308    <repeatable>true</repeatable>
309    <binding>
310     <command>nasal</command>
311     <script>
312       if (getprop("/sim/gui/d-button")){
313         setprop("/sim/current-view/x-offset-m", 
314           -0.01 + getprop("/sim/current-view/x-offset-m"));
315       } else {
316         view.panViewDir(1)
317       }
318     </script>
319    </binding>
320   </low>
321   <high>
322    <repeatable>true</repeatable>
323    <binding>
324     <command>nasal</command>
325     <script>
326       if (getprop("/sim/gui/d-button")){
327         setprop("/sim/current-view/x-offset-m", 
328           0.01 + getprop("/sim/current-view/x-offset-m"));
329       } else {
330         view.panViewDir(-1)
331       }
332     </script>
333    </binding>
334   </high>
335 </axis>
336
337 <axis> <!-- 8/7/7 -->
338   <desc>View Tilt Up/Down (D-shift: move PoV)</desc>
339   <number>
340    <unix>8</unix>
341    <mac>7</mac>
342    <windows>7</windows>
343   </number>
344   <low>
345    <repeatable>true</repeatable>
346    <binding>
347     <command>nasal</command>
348     <script>
349       if (getprop("/sim/gui/d-button")){
350         setprop("/sim/current-view/y-offset-m", 
351           0.01 + getprop("/sim/current-view/y-offset-m"));
352       } else {
353         view.panViewPitch(1)
354       }
355     </script>
356    </binding>
357   </low>
358   <high>
359    <repeatable>true</repeatable>
360    <binding>
361     <command>nasal</command>
362     <script>
363       if (getprop("/sim/gui/d-button")){
364         setprop("/sim/current-view/y-offset-m", 
365           -0.01 + getprop("/sim/current-view/y-offset-m"));
366       } else {
367         view.panViewPitch(-1)
368       }
369     </script>
370    </binding>
371   </high>
372 </axis>
373
374
375 <!-- End of axes;  now on to buttons -->
376
377 <button n="1">
378    <desc>(FIRE) : Auto-Coordination off (D-shift: on)</desc>
379    <binding>
380     <command>nasal</command>
381     <script>
382       setprop("/controls/flight/auto-coordination", ! !getprop("/sim/gui/d-button"));
383     </script>
384    </binding>
385 </button>
386
387
388 <button n="3">
389    <desc>(B) : Zoom out i.e. increase field of view (D-shift: zoom in)</desc>
390    <repeatable type="bool">true</repeatable>
391    <binding>
392     <command>nasal</command>
393     <script>
394       if ( getprop("/sim/gui/d-button") ) {
395         view.decrease(0.5)              # zoom in
396       } else {
397         view.increase(0.5)              # zoom out
398       }
399     </script>
400    </binding>
401 </button>
402
403 <button n="4">
404   <desc>(C) : Reset View</desc>
405   <binding>
406    <command>nasal</command>
407    <script>
408      view.resetView();          # only resets tilt/pan/zoom:
409                                 # must reset x/y/z view point separately
410      vn = getprop("/sim/current-view/view-number");
411      conf = sprintf("/sim/view[%d]/config", vn);
412      foreach (parm ; ["x-offset-m", "y-offset-m", "z-offset-m"]) {
413        setprop("/sim/current-view/", parm, getprop(conf, parm));
414      }
415    </script>
416   </binding>
417 </button>
418
419 <!-- Main brakes (not parking brakes) :: pinky subtrigger -->
420 <button n="5">
421   <desc>(Pinky) : Brakes</desc>
422   <binding>
423    <command>nasal</command>
424    <script>controls.applyBrakes(1)</script>
425   </binding>
426   <mod-up>
427    <binding>
428     <command>nasal</command>
429     <script>controls.applyBrakes(0)</script>
430    </binding>
431   </mod-up>
432 </button>
433
434 <!-- Shift :: (D) button -->
435 <button n="6">
436   <desc>(D) : Shift Key</desc>
437   <binding>
438    <command>nasal</command>
439    <script>
440      setprop("/sim/gui/d-button", 1);
441    </script>
442   </binding>
443   <mod-up>
444    <binding>
445     <command>nasal</command>
446     <script>
447       setprop("/sim/gui/d-button", 0);
448     </script>
449    </binding>
450   </mod-up>
451 </button>
452
453
454   <!-- gear handle up/down :: button T1/T2 -->
455   <button n="8">
456    <desc>(T1) : Landing Gear Handle Up</desc>
457     <binding>
458      <command>nasal</command>
459       <script>
460        controls.gearDown(-1)
461      </script>
462     </binding>
463   </button>
464   <button n="9">
465     <desc>(T2) : Landing Gear Handle Down</desc>
466     <binding>
467      <command>nasal</command>
468      <script>
469        controls.gearDown(1)
470      </script>
471     </binding>
472   </button>
473
474
475 <!-- Pitch trim :: stick upper hat Up/Dn -->
476 <button n="15">
477   <desc>Elevator trim down</desc>
478   <repeatable type="bool">true</repeatable>
479   <binding>
480    <command>nasal</command>
481    <script>controls.elevatorTrim(0.6)</script>
482   </binding>
483 </button>
484 <button n="17">
485   <desc>Elevator trim up</desc>
486   <repeatable type="bool">true</repeatable>
487   <binding>
488    <command>nasal</command>
489    <script>controls.elevatorTrim(-0.6)</script>
490   </binding>
491 </button>
492
493 <!-- Rudder trim :: stick upper hat L/R -->
494 <button n="16">
495   <desc>(Throttle Rocker) : Rudder trim right</desc>
496   <repeatable type="bool">true</repeatable>
497   <binding>
498    <command>nasal</command>
499    <script>controls.rudderTrim(1)</script>
500   </binding>
501 </button>
502 <button n="18">
503   <desc>(Throttle Rocker) : Rudder trim left</desc>
504   <repeatable type="bool">true</repeatable>
505   <binding>
506    <command>nasal</command>
507    <script>controls.rudderTrim(-1)</script>
508   </binding>
509 </button>
510
511 <!-- Flaps (shift: Speed Brakes) :: T3/T4 -->
512 <button n="10">
513   <desc>(T3) : Decrease flaps (shift: Speed Brakes extend)</desc>
514   <binding>
515    <command>nasal</command>
516    <script>
517      if ( getprop("/sim/gui/d-button") ) {
518        setprop("/controls/flight/speedbrake", 1);
519      } else {
520        controls.flapsDown(-1)
521      }
522    </script>
523   </binding>
524   <mod-up>
525    <binding>
526     <command>nasal</command>
527     <script>
528       if ( getprop("/sim/gui/d-button") ) {
529         
530       } else {
531         controls.flapsDown(0)
532       }
533     </script>
534    </binding>
535   </mod-up>
536 </button>
537 <button n="11">
538   <desc>(T4) : Increase flaps (shift: Speed Brakes retract)</desc>
539   <binding>
540    <command>nasal</command>
541    <script>
542      if ( getprop("/sim/gui/d-button") ) {
543        setprop("/controls/flight/speedbrake", 0);
544      } else {
545        controls.flapsDown(1)
546      }
547    </script>
548   </binding>
549   <mod-up>
550    <binding>
551     <command>nasal</command>
552     <script>
553       if ( getprop("/sim/gui/d-button") ) {
554         
555       } else {
556         controls.flapsDown(0)
557       }
558     </script>
559    </binding>
560   </mod-up>
561 </button>
562
563   <!-- Carb Heat (shift: Cowl Flaps) :: T6/T5 -->
564   <button n="12">
565     <desc>(T5) : Carb Heat On (shift: Cowl Flaps Close)</desc>
566     <binding>
567      <command>nasal</command>
568      <script>
569        if ( getprop("/sim/gui/d-button") ) {
570          props.setAll("/controls/engines/engine", "cowl-flaps-norm", 1);
571        } else {
572          props.setAll("/controls/engines/engine", "carb-heat", 0);
573        }
574      </script>
575     </binding>
576   </button>
577   <button n="13">
578     <desc>(T6) : Carb Heat Off (shift: Cowl Flaps Open)</desc>
579     <binding>
580      <command>nasal</command>
581      <script>
582        if ( getprop("/sim/gui/d-button") ) {
583          props.setAll("/controls/engines/engine", "cowl-flaps-norm", 0);
584        } else {
585          props.setAll("/controls/engines/engine", "carb-heat", 1);
586        }
587      </script>
588     </binding>
589   </button>
590
591 <!-- Aileron trim :: throttle rocker -->
592 <button n="20">
593   <desc>Aileron trim right</desc>
594   <repeatable type="bool">true</repeatable>
595   <binding>
596    <command>nasal</command>
597    <script>controls.aileronTrim(0.5)</script>
598   </binding>
599 </button>
600 <button n="22">
601   <desc>Aileron trim left</desc>
602   <repeatable type="bool">true</repeatable>
603   <binding>
604    <command>nasal</command>
605    <script>controls.aileronTrim(-0.5)</script>
606   </binding>
607 </button>
608
609
610 <!-- Mode roller switch (buttons 23-25).   -->
611 <!-- Just put it in the property tree,     -->
612 <!-- in case somebody wants to look at it. -->
613 <button n="23">
614   <desc>Mode 1</desc>
615   <binding>
616    <command>nasal</command>
617    <script>
618      setprop("/input/joysticks/js/saitek-x52-mode",1)
619    </script>
620   </binding>
621 </button>
622 <button n="24">
623   <desc>Mode 2</desc>
624   <binding>
625    <command>nasal</command>
626    <script>
627      setprop("/input/joysticks/js/saitek-x52-mode",2)
628    </script>
629   </binding>
630 </button>
631 <button n="25">
632   <desc>Mode 3</desc>
633   <binding>
634    <command>nasal</command>
635    <script>
636      setprop("/input/joysticks/js/saitek-x52-mode",3)
637    </script>
638   </binding>
639 </button>
640
641 <button n="26">
642   <desc>(MFD Func) : Stopwatch timer becomes clock again</desc>
643   <binding>
644    <command>nasal</command>
645    <script>
646       props.globals.getNode("/instrumentation/clock/offset-sec", 1).setValue(0);
647    </script>
648   </binding>
649 </button>
650
651 <button n="28">
652   <desc>(MFD Reset) : Stopwatch timer reset</desc>
653   <binding>
654    <command>nasal</command>
655    <script>
656    <!-- Note that the "indicated-sec" variable is a large number,
657      probably seconds since midnight ... *not* modulo 60. -->
658       ttt = props.globals.getNode("/instrumentation/clock/indicated-sec", 1).getValue();
659       node = props.globals.getNode("/instrumentation/clock/offset-sec", 1);
660       off = node.getValue();
661       node.setValue(off-ttt);
662    </script>
663   </binding>
664 </button>
665
666 <!-- (i) button :: unbound key -->
667 <!-- just put it in the property tree -->
668 <button n="29">
669   <desc>Mode 1</desc>
670   <binding>
671     <command>nasal</command>
672     <script>
673       setprop("/input/joysticks/js/saitek-x52-i",1)
674     </script>
675   </binding>
676   <mod-up><binding>
677     <command>nasal</command>
678     <script>
679       setprop("/input/joysticks/js/saitek-x52-i",0)
680     </script>
681   </binding></mod-up>
682 </button>
683
684
685 <!-- Parking brake :: unbound function -->
686 <button n="666">
687    <desc>Toggle parking brake on or off</desc>
688    <binding>
689      <command>property-toggle</command>
690      <property>/controls/gear/brake-parking</property>
691    </binding>
692 </button>
693
694 </PropertyList>