-- Saitek Cyborg 3-D Rumble Force --
This thread needs to be turned into a sticky. I JUST found it after nearly abandoning FlightGear as unusable. I was helped by a reader who does not post and wishes to remain anonymous, but he saw my plight and PM'ed me. He got me started down the road to creating my joystick configuration. I was not happy with FlightGear, because it just did not respond in a realistic manner. Honestly, the standard joystick code needs to be re-written to tame sticks to the newer, faster computers, but the reality is this has been a problem from the start. I first tried FlightGear back in 2000, and for this reason I never paid serious attention to FG. Now, with my joystick tamed down, it flies better than X-Plane. Plus, being able to tailor the joystick (to each plane, if you feel like it) makes Flight gear infinitely more configurable than X-Plane!
All of that said, I will share my Joystick file here. It is for the Saitek Cyborg 3D Rumble Force. It is a work in progress, but at this point it controls aileron and elevator trim from the Hat switch, rudder trim from buttons 2 & 5, HUD control on button 3, gear toggle is on button 4 (gear won't retract if there is weight on them), with flaps on 6 & 7, and gear up & down on 8 & 9 (this is a hold over - these two buttons will be re-purposed). The Trigger is a shifter. With the trigger depressed, the Hat controls Look About, button 3 toggles HUD color, and button 4 pauses the sim. I have plans for shifted functions for buttons 6 thru 9. My stick is noisy so there is a wide dead band, axis control (except for the Throttle) is logarithmic for more realism, and sensitivity is tamed to a manageable, more realistic level. The Twist axis is not active (this does not realistically simulate rudder control, auto-coordination is better).
- Code: Select all
<?xml version="1.0"?>
<PropertyList>
<name type="string">Saitek Cyborg 3D Rumble Force</name>
<!-- Mod 1 - Script defining Multifunctionality -->
<data>
<modeTrig type="bool">false</modeTrig>
</data>
<nasal>
<script>
<![CDATA[
var self = cmdarg().getParent();
var data = self.getNode("data");
var modeTrig = data.getNode("modeTrig");
var trace = func(str) {
# Uncomment the line below to trace button presses.
# print("Cyborg xml Model: " ~ model ~ str);
}
#
]]>
</script>
</nasal>
<!-- End Mod 1-->
<axis>
<!-- Axis 0. Roll left/right -->
<dead-band type="double">0.15</dead-band>
<desc type="string">Aileron</desc>
<binding>
<command type="string">property-scale</command>
<property type="string">/controls/flight/aileron</property>
<factor type="double">0.55</factor>
<offset type="double">0</offset>
<power type="int">3</power>
</binding>
</axis>
<axis n="1">
<!-- Analog axis 1. Pitch back/forward -->
<dead-band type="double">0.15</dead-band>
<desc type="string">Elevator</desc>
<binding>
<command type="string">property-scale</command>
<property type="string">/controls/flight/elevator</property>
<factor type="double">-0.55</factor>
<offset type="double">0</offset>
<power type="int">3</power>
</binding>
</axis>
<axis n="2">
<!--Analog axis 2. Throttle -->
<desc type="string">Throttle</desc>
<binding>
<command type="string">nasal</command>
<script type="string">controls.throttleAxis();</script>
</binding>
</axis>
<!-- Mod 1 - Multifuctionality with the Trigger as the Shift -->
<!-- Trigger Button -->
<button n="0">
<name>Trigger</name>
<desc>Trigger mode '+Trg'; +Shift: trigger</desc>
<binding>
<command>nasal</command>
<script>
trace("Trig Bttn bit 0 press");
modeTrig.setIntValue(1);
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
trace("Trig Bttn bit 0 release");
modeTrig.setIntValue(0);
controls.trigger(0);
</script>
</binding>
</mod-up>
</button>
<!-- Axis 4. Hat left/right - Aileron Trim; +Trig, Lateral View-->
<axis n="4">
<desc>Aileron Trim; +Trg: Pan View</desc>
<low>
<repeatable type="bool">true</repeatable>
<interval-sec type="double">0.1</interval-sec>
<binding>
<command>nasal</command>
<script>
<![CDATA[
if (! modeTrig.getBoolValue()) {
setprop("controls/flight/aileron-trim",
(getprop("controls/flight/aileron-trim") -0.0015));
} else {
setprop("/sim/current-view/heading-offset-deg",
(getprop("/sim/current-view/heading-offset-deg") + 4.000));
}
]]>
</script>
</binding>
</low>
<high>
<repeatable type="bool">true</repeatable>
<interval-sec type="double">0.1</interval-sec>
<binding>
<command>nasal</command>
<script>
<![CDATA[
if (! modeTrig.getBoolValue()) {
setprop("controls/flight/aileron-trim",
(getprop("controls/flight/aileron-trim") +0.0015));
} else {
setprop("/sim/current-view/heading-offset-deg",
(getprop("/sim/current-view/heading-offset-deg") - 4.000));
}
]]>
</script>
</binding>
</high>
</axis>
<!-- Axis 5. Hat up/down - Elevator Trim; +Trig, Vertical View-->
<axis n="5">
<desc>Elevator Trim; +Trg: Tilt view</desc>
<low>
<repeatable type="bool">true</repeatable>
<interval-sec type="double">0.1</interval-sec>
<binding>
<command>nasal</command>
<script>
<![CDATA[
if (! modeTrig.getBoolValue()) {
setprop("controls/flight/elevator-trim",
(getprop("controls/flight/elevator-trim") +0.002));
} else {
setprop("/sim/current-view/pitch-offset-deg",
(getprop("/sim/current-view/pitch-offset-deg") - 1.500));
}
]]>
</script>
</binding>
</low>
<high>
<repeatable type="bool">true</repeatable>
<interval-sec type="double">0.1</interval-sec>
<binding>
<command>nasal</command>
<script>
<![CDATA[
if (! modeTrig.getBoolValue()) {
setprop("controls/flight/elevator-trim",
(getprop("controls/flight/elevator-trim") -0.002));
} else {
setprop("/sim/current-view/pitch-offset-deg",
(getprop("/sim/current-view/pitch-offset-deg") + 1.500));
}
]]>
</script>
</binding>
</high>
</axis>
<!-- End Mod 1-->
<button n="1">
<desc type="string">Rudder Trim Left</desc>
<binding>
<command type="string">nasal</command>
<script type="string">controls.rudderTrim(-1);</script>
</binding>
<repeatable type="double">1</repeatable>
</button>
<!-- Mod 3 - Landing Gear Toggle; +Trigger, Pauses Sim -->
<button n="3">
<name>Button #4</name>
<desc>Togg Landing Gear; +Trg: Pause </desc>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>
if (modeTrig.getBoolValue()) {
trace("Trig Button #4 bit 1 press");
if (getprop("sim/freeze/master") == 0 ) {
setprop("sim/freeze/master", 1);
} else {
setprop("sim/freeze/master", 0);
}
if (getprop("sim/freeze/clock") == 0 ) {
setprop("sim/freeze/clock", 1);
} else {
setprop("sim/freeze/clock", 0);
}
} else {
trace(" Button #4 bit 1 press");
controls.gearToggle()
}
</script>
</binding>
</button>
<!-- End Mod 3 -->
<!-- Mod 2 - Assign HUD control to Joystick; +Trigger, Toggles HUD color -->
<button n="2">
<name>Button #3</name>
<desc>HUD Toggle; +Trg HUD Type</desc>
<binding>
<command>nasal</command>
<script>
trace("Button #3 Bit 2 press ");
if (modeTrig.getBoolValue()) {
aircraft.HUD.cycle_color();
} else {
aircraft.HUD.cycle_type();
}
</script>
</binding>
</button>
<!-- End Mod 2 -->
<button n="4">
<desc type="string">Rudder Trim Right</desc>
<binding>
<command type="string">nasal</command>
<script type="string">controls.rudderTrim(1);</script>
</binding>
<repeatable type="double">1</repeatable>
</button>
<button n="5">
<desc type="string">Flaps Up</desc>
<repeatable type="string">false</repeatable>
<binding>
<command type="string">nasal</command>
<script type="string">controls.flapsDown(-1);</script>
</binding>
<mod-up>
<binding>
<command type="string">nasal</command>
<script type="string">controls.flapsDown(0);</script>
</binding>
</mod-up>
</button>
<button n="6">
<desc type="string">Flaps Down</desc>
<repeatable type="string">false</repeatable>
<binding>
<command type="string">nasal</command>
<script type="string">controls.flapsDown(1);</script>
</binding>
<mod-up>
<binding>
<command type="string">nasal</command>
<script type="string">controls.flapsDown(0);</script>
</binding>
</mod-up>
</button>
<button n="7">
<desc type="string">Gear Down</desc>
<repeatable type="string">false</repeatable>
<binding>
<command type="string">nasal</command>
<script type="string">controls.gearDown(1);</script>
</binding>
<mod-up>
<binding>
<command type="string">nasal</command>
<script type="string">controls.gearDown(0);</script>
</binding>
</mod-up>
</button>
<button n="8">
<desc type="string">Gear Up</desc>
<repeatable type="string">false</repeatable>
<binding>
<command type="string">nasal</command>
<script type="string">controls.gearDown(-1);</script>
</binding>
<mod-up>
<binding>
<command type="string">nasal</command>
<script type="string">controls.gearDown(0);</script>
</binding>
</mod-up>
</button>
</PropertyList>
As I said, this is a work in progress. When I get this file doing what I really want it to do, I will post it again. Then I will start to work re-mapping the keyboard as a joystick complement, not a primary flight control. I hope you enjoy this, and find it useful