Hi fellow wiki editors!

To help newly registered users get more familiar with the wiki (and maybe older users too) there is now a {{Welcome to the wiki}} template. Have a look at it and feel free to add it to new users discussion pages (and perhaps your own).

I have tried to keep the template short, but meaningful. /Johan G

Changes

Jump to: navigation, search

Writing Joystick Code: Part 3

775 bytes removed, 10:04, 5 December 2015
m
no edit summary
{{WIP}}
 
{{JoystickScripting Navigation}}
== Special snippets ==
-----------------------------------------------------------------------------
To toggle the Parking brake, use this. Entire code-block shown. Non-repeatable button. (You have to specifically set <repeatable> to true if you want repeatable. It is assumed to be false.)
<syntaxhighlight lang="xml">
<button n="1">
</button>
</syntaxhighlight>
This method can be used to toggle any property that is on/off. Use Debug - Browse Internal Properties to find suitable candidates. Also see getProp, setProp and setAll below.
Remember, it ''toggles'' the property, you can't use it to set the property into a specific state.
-----------------------------------------------------------------------------
To make condition work with mixture on a lever (axis). This is pertinent to turboprops.
Change
controls.mixtureAxis()
to
controls.mixtureAxis();
props.setAll("controls/engines/engine", "condition", getprop("controls/engines/engine/mixture"))
-----------------------------------------------------------------------------
To make condition work with mixture on a non-repeatable buttonlever (axis). This is pertinent to turboprops. Change Make mixture richer NR <syntaxhighlight langpre style="xml">white-space: pre-wrap; <![CDATA[ white-space: -moz-pre-wrap; if(getprop("controls/engines/engine/mixture") < 1 ) {white-space: -pre-wrap; setprop("controls/engines/engine/mixture", getprop ("controls/engines/engine/mixture") + 0.05)white-space: -o-pre-wrap; props.setAll(word-wrap: break-word"> controls/engines/engine", "condition", getprop.mixtureAxis("controls/engines/engine/mixture")) } ]]> </syntaxhighlightpre> to Make mixture leaner NR <![CDATA[ if(getprop(pre style="controls/engines/engine/mixture") > 0 ) {white-space: pre-wrap; setprop("controls/engines/engine/mixture", getprop("controls/engines/engine/mixture") white-space: - 0.05)moz-pre-wrap; props.setAll("controls/engines/engine", "condition", getprop("controls/engines/engine/mixture"))white-space: -pre-wrap; }white-space: -o-pre-wrap; ]]word-wrap: break-word"> Make mixture richer R <![CDATA[ if(getprop("controls/engines/engine/mixture") < 1 ) { setprop.mixtureAxis("controls/engines/engine/mixture", getprop ("controls/engines/engine/mixture") + 0.001); props.setAll("controls/engines/engine", "condition", getprop("controls/engines/engine/mixture")) } ]]> Make mixture leaner R <![CDATA[ if(getprop("controls/engines/engine/mixture") pre> 0 ) { setprop("controls/engines/engine/mixture", getprop("controls/engines/engine/mixture") - 0.001) props.setAll("controls/engines/engine", "condition", getprop("controls/engines/engine/mixture")) } ]]>----------------------------------------------------------------------------
-----------------------------------------------------------------------------
 
 
This is an alternative method to adjust a property
<repeatable>true</repeatable>
</binding>
This will continuously reduce /sim/current-view/goal-pitch-offset-deg in steps of 2 while the button is held in.
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
 
 
 
== Advanced Programming ==
=== if ... then ... else ===
Sometimes you only want to do something if a certain condition is true (or false.) In this case you use an if clause. The general form in most programming languages is if (condition) then action endif
We write : '''if''' '''('''condition''')''' '''then as {, and endif as }.And each "''' action" is terminated by a semicolon:'''endif'''
<syntaxhighlight lang=In Nasal, we write "phpthen" as ">  if (condition) { # the opening curly brace means THEN action; " and "endif" as "} # the closing curly brace means ENDIF, i".e. end of this blockEach "action" (or statement) is terminated by a semicolon:
<syntaxhighlight lang="nasal">
if (condition)
{ # the opening curly brace means THEN
action;
} # the closing curly brace means ENDIF, i.e. end of this block
</syntaxhighlight>
Actions can be arbitrary Nasal expressions, including function calls and other conditional blocks.
==== An example ====
Lets say that if x is less than 5 we want to add 2 to it. We write:
<syntaxhighlight lang="phpnasal"> if (x < 5) { x = x + 2; }
</syntaxhighlight>
The more readable way of writing it is
<syntaxhighlight lang="phpnasal"> if (x < 5) { x = x + 2; }</syntaxhighlight> And we can even omit the braces if there's only one action:<syntaxhighlight lang="nasal">if (x < 5) # no opening brace... x = x + 2; # ...so the if statement ends at the first semicolon
</syntaxhighlight>
If we also want to add 1 to y if the condition is true, we write
<syntaxhighlight lang="phpnasal"> if (x < 5) { x = x + 2; y + = y + 1; }
</syntaxhighlight>
For example:
<syntaxhighlight lang="phpnasal"> if (x < 5) { x += 2; # means x = x + 2 y += 1; # means y = y + 1 }
</syntaxhighlight>
Now lets pretend that we still want to increase x by 2 if it less than 5, and if it is 5 or more we want to add 1 to it. We use else.
It looks like this
<syntaxhighlight lang="phpnasal"> if (x < 5) { x = x + 2; } else { x = x + 1; }
</syntaxhighlight>
Now lets say we have the following rules:
* If x < 5 add 2 to it * If x < 10 add 1 to it * If x is 10 or more add 7 to it. In this case elseif becomes useful.
In English our code would be
* If (x < 5) then (x = x + 2) else if (x < 10) then (x = x + 1). * If none of these are true then (x = x + 7). * End of if clause.
We test for x < 5 first. If it fails we test for x < 10. If x , 5 succeeds we do (x = x + 2) and then move on past the end of if clause.
Writing our code properly we get
<syntaxhighlight lang="phpnasal">  if (x < 5) { x = x + 2; } elseif elsif (x < 10) { x = x + 1; } else { x = x + 7; }
</syntaxhighlight>
You can use more than one elseifelsif, but it gets messy. If you have a number of tests then it is might be better to test for each case individually.Easier to understand each condition separately and much less chance of an error.
Our above example would become
<syntaxhighlight lang="phpnasal"> if (x < 5) { x = x + 2; } if (x >= 5) and (x < 10) { x = x + 1; } if (x >= 10) { x = x + 7; }
</syntaxhighlight>
But the advantage is that we are forced to write out each condition exactly as it should be tested. Easier to understand and easier to maintain.
==== Another example ====
Lets say that you want something to happen only if the gear is up. But the only property you can read is Gear-DownGearDown. Then you write<syntaxhighlight lang="phpnasal"> if (!Gear-DownGearDown) { action; }
</syntaxhighlight>
 
The ! means not. So it translates as: If the gear is not down perform action.
 
 
Beacuse we use < and > we will need to enclose it all with CDATA, in order not to mess up the XML syntax.
See the discussion of variables below for an example of the use of if.
]]>
You need CDATa CDATA because of the less-than sign.
You can use this for throttle, propeller, mixture and condition.
BTW Here the props in props.setAll is short for property, not propellers.
 
'''Method 1'''
<nowiki> <data>
<mode type="int">1</mode> # Initialise mode to 1
</data>
<nasal>
<script>
<nowiki><![CDATA[
var self = cmdarg().getParent();
var data = self.getNode("data");
var mode = data.getNode("mode");
get_mode = func { mode.getValue() ; } ]]> </script>
</nasal>
var m # Used whenever mode is accessed </nowiki>
This goes right at the top of your xml file, just after </name>.
The code for the button (non-repeatable)that changes mode looks like this
var m = get_mode();
m = m + 1;
if (m == 4) {
When a button is pressed, the code looks like this
var m = get_mode();
if (m == 1) {
ground-action
be used somewhere in the system files. In the xml file for the Saitek Yoke, where I use a variable to control the assignments
of the levers on the quadrant, I call the variable ''SaitekMultiMode''. Unlikely to be used by the FG programmers, or anybody else.
 
 
=== perIndexAxisHandler ===
See [http://forum.flightgear.org/forums/viewtopic.php?f=24&t=17851 this post] for an example of using this.
Go back to [[Writing Joystick Code: Part 2]] Go forward to [[Writing Joystick Code: Part 4]]  -----------------------------------------------------------------------------  Any complaints/suggestions/questions/kudos can be posted [http://forum.flightgear.org/forums/viewtopic.php?f=24&t=17892 here].
6
edits

Navigation menu