20,741
edits
m (moved Howto: Port I/O from Nasal to Howto:Port I/O from Nasal: Robot: Moved page) |
mNo edit summary |
||
| Line 1: | Line 1: | ||
{{PropertyTree}} | |||
== Introduction == | == Introduction == | ||
You can't really 'access' a device from [[Nasal]] directly. What you'll most likely want to do is define a [[generic protocol]] for the properties you're interested in sending between fgfs and your device. A generic protocol allows you to easily import external data into [[FlightGear]]'s [[property tree]] and export properties, too. | You can't really 'access' a device from [[Nasal]] directly. What you'll most likely want to do is define a [[generic protocol]] for the properties you're interested in sending between fgfs and your device. A generic protocol allows you to easily import external data into [[FlightGear]]'s [[property tree]] and export properties, too. | ||
| Line 14: | Line 16: | ||
In Nasal, you could use a conventional setprop() call to set a property, which is then picked up by the I/O subsystem and sent to its destination (e.g. serial port/network). | In Nasal, you could use a conventional setprop() call to set a property, which is then picked up by the I/O subsystem and sent to its destination (e.g. serial port/network). | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
setprop("/myoutput-property/data", "my data"); | setprop("/myoutput-property/data", "my data"); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 61: | Line 63: | ||
Now, to send a message, you would only need to modify the property - for example, by using setprop: | Now, to send a message, you would only need to modify the property - for example, by using setprop: | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
setprop('/sim/cockpit/eufd', 'Hello World'); | setprop('/sim/cockpit/eufd', 'Hello World'); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 67: | Line 69: | ||
But you could also create a wrapper named "sendMessage" for this purpose: | But you could also create a wrapper named "sendMessage" for this purpose: | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
var sendMessage = func(msg) { | var sendMessage = func(msg) { | ||
print("Sending message:", msg); | print("Sending message:", msg); | ||
| Line 76: | Line 78: | ||
Now, you could also create additional wrappers to do device-specific things, like clearing the LCD screen, setting the font color, font size, positioning the cursor etc, simply by adding device specific commands to each wrapper: | Now, you could also create additional wrappers to do device-specific things, like clearing the LCD screen, setting the font color, font size, positioning the cursor etc, simply by adding device specific commands to each wrapper: | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
var setFontColor = func(color) { | var setFontColor = func(color) { | ||
sendMessage("0xFF,0xAC,0xEF...."); | sendMessage("0xFF,0xAC,0xEF...."); | ||
| Line 82: | Line 84: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
var setHeading = func(heading) { | var setHeading = func(heading) { | ||
sendMessage("0xFF,0xCA,0xFA,$"~heading); | sendMessage("0xFF,0xCA,0xFA,$"~heading); | ||
| Line 91: | Line 93: | ||
You could then register a listener that is automatically invoked whenever the "input property" is modified, this will automatically invoke your Nasal callback (i.e. a Nasal function) so that you can process the input. | You could then register a listener that is automatically invoked whenever the "input property" is modified, this will automatically invoke your Nasal callback (i.e. a Nasal function) so that you can process the input. | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
var processMessage = func() { | var processMessage = func() { | ||
print("Info: Message received!"); | print("Info: Message received!"); | ||
| Line 101: | Line 103: | ||
Obviously, you could now add some header to each message to identify the message type. For example, by checking a substring of the message: | Obviously, you could now add some header to each message to identify the message type. For example, by checking a substring of the message: | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
var processMessage = func() { | var processMessage = func() { | ||
var msg = getprop('/sim/cockpit/eufd-input'); | var msg = getprop('/sim/cockpit/eufd-input'); | ||
| Line 113: | Line 115: | ||
Next, you could come up with a list of supported message types: | Next, you could come up with a list of supported message types: | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
var processMessage = func() { | var processMessage = func() { | ||
var msg_types = {'A':'SET FONT','B':'CLEAR SCREEN','C':'RESET','D':'SHUTDOWN','E':'NOP'}; | var msg_types = {'A':'SET FONT','B':'CLEAR SCREEN','C':'RESET','D':'SHUTDOWN','E':'NOP'}; | ||
| Line 127: | Line 129: | ||
You can also directly use hexadecimal values: | You can also directly use hexadecimal values: | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
var ESC=0x32; | var ESC=0x32; | ||
var ACK=0x13; | var ACK=0x13; | ||
| Line 143: | Line 145: | ||
For your data processing needs (formatting, conversion, marshalling, compression etc), you can use a combination of the sprintf() library function, and the [http://gitorious.org/fg/fgdata/blobs/master/Nasal/bits.nas bits.nas module in $FG_ROOT/bits.nas]. | For your data processing needs (formatting, conversion, marshalling, compression etc), you can use a combination of the sprintf() library function, and the [http://gitorious.org/fg/fgdata/blobs/master/Nasal/bits.nas bits.nas module in $FG_ROOT/bits.nas]. | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="nasal"> | ||
var output_property = '/sim/cockpit/eufd'; | var output_property = '/sim/cockpit/eufd'; | ||
var data = sprintf( "offset:%x", 255 ); | var data = sprintf( "offset:%x", 255 ); | ||