Telnet usage: Difference between revisions

+-link: Interactive traffic → AI Traffic; Spelling; minor cleanup
mNo edit summary
(+-link: Interactive traffic → AI Traffic; Spelling; minor cleanup)
Line 4: Line 4:
FlightGear can be configured to act like a telnet or even an http "server". It can watch a port for incoming connections and respond appropriately, these built-in daemons (servers) support multiple concurrent connections.  
FlightGear can be configured to act like a telnet or even an http "server". It can watch a port for incoming connections and respond appropriately, these built-in daemons (servers) support multiple concurrent connections.  


FG has a low bandwidth "command" (aka telnet/props) interface where you can interactively (or automatically via an external program) examine and modify just about any internal variable in the sim. This gives you a great capability to do external scripting, external operater gui's, etc. For instance, if you have your own GUI for operating the sim and want to use it to set weather conditions, you can leverage the FG telnet interface to have your own program remotely configure the environmental settings in all your FG based visual channels.
FlightGear has a low bandwidth "command" (aka telnet/props) interface where you can interactively (or automatically via an external program) examine and modify just about any internal variable in the sim. This gives you a great capability to do external scripting, external operator GUI's, etc. For instance, if you have your own GUI for operating the sim and want to use it to set weather conditions, you can leverage the FlightGear telnet interface to have your own program remotely configure the environmental settings in all your FlightGear based visual channels.


Many things (view parameters, weather, time of day, etc.) are configurable via the property system. For things like weather and view selection which don't change rapidly, you can send over new property values using the "telnet" interface. For things that could change rapidly (like view position/orientation) you probably want to blast over udp packets at 60hz or whatever your screen refresh rate.
Many things (view parameters, weather, time of day, etc.) are configurable via the property system. For things like weather and view selection which don't change rapidly, you can send over new property values using the "telnet" interface. For things that could change rapidly (like view position/orientation) you probably want to blast over UDP packets at 60hz or whatever your screen refresh rate.


The telnet server can be activated with the <code>--telnet=port</code> [[Command Line Parameters|command line option]], where port is the number of the listening port that will be opened locally by the FlightGear fgfs process (note that the --props parameter is equivalent).
The telnet server can be activated with the <code>--telnet=port</code> [[Command Line Parameters|command line option]], where port is the number of the listening port that will be opened locally by the FlightGear fgfs process (note that the --props parameter is equivalent).
Line 21: Line 21:
This makes it possible to "remote control" FlightGear by using the telnet protocol. This can for example be used to change environment settings (weather, time, visibility etc). But you can also remotely fail equipment: Use the telnet/http interface to unset the "serviceable" flags on the affected instruments and systems.  All you need to write is a little script (perl,python, netcat) to do the 25-to-1 multiplex/demultiplex operation.
This makes it possible to "remote control" FlightGear by using the telnet protocol. This can for example be used to change environment settings (weather, time, visibility etc). But you can also remotely fail equipment: Use the telnet/http interface to unset the "serviceable" flags on the affected instruments and systems.  All you need to write is a little script (perl,python, netcat) to do the 25-to-1 multiplex/demultiplex operation.


Many internals are exposed through the  property tree, which is accesible in many ways. There is a http and a telnet interface ready for use. A powerful thing is the  interface with a freely configurable protocol to send and receive properties.  This interface can talk via tcp or udp.
Many internals are exposed through the  property tree, which is accessible in many ways. There is a http and a telnet interface ready for use. A powerful thing is the  interface with a freely configurable protocol to send and receive properties.  This interface can talk via TCP or UDP.


So you need some kind of gui to trigger the failures, a layer that translates  this to flightgear properties and a communication layer that communicates  
So you need some kind of GUI to trigger the failures, a layer that translates  this to FlightGear properties and a communication layer that communicates  
with the flightgear instances. This is an independent application, so you can  write it in c, c++, c#, java, php or whatever you like, but you might keep  
with the FlightGear instances. This is an independent application, so you can  write it in C, C++, C#, Java, PHP or whatever you like, but you might keep  
cross platform usability in mind.
cross platform usability in mind.


Probably not every aircraft developer has implented every failure feature in his aircraft, since most of them are happy if the "normal procedures" work.  
Probably not every aircraft developer has implemented every failure feature in his aircraft, since most of them are happy if the "normal procedures" work.  
Also, some systems are implemented, some are not. So for most GA aircraft for example, the landing gear has no model for the hydraulic system but a  
Also, some systems are implemented, some are not. So for most GA aircraft for example, the landing gear has no model for the hydraulic system but a  
simple "if you operate the gear lever, the gear is extending" functionality.
simple "if you operate the gear lever, the gear is extending" functionality.


But a telnet connection can also be used for inserting scenery objects or [[Interactive traffic|AI aircraft]] models dynamically. It is also possible to trigger arbitrary [[Nasal]] code by writing to a property with a registered Nasal listener. In fact, it is even possible to insert and run Nasal code via telnet, by writing the code to a property and call()'ing it then [http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg00150.html][http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg00965.html].
But a telnet connection can also be used for inserting scenery objects or [[AI Traffic|AI aircraft]] models dynamically. It is also possible to trigger arbitrary [[Nasal]] code by writing to a property with a registered Nasal listener. In fact, it is even possible to insert and run Nasal code via telnet, by writing the code to a property and call()'ing it then [http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg00150.html][http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg00965.html].


Information on nearby multiplayer entities is provided in the property tree so you can access this information at least within flightgear.  You could
Information on nearby multiplayer entities is provided in the property tree so you can access this information at least within FlightGear.  You could
query this data via the property interface, or build some sort of nasal script.   
query this data via the property interface, or build some sort of nasal script.   


Line 40: Line 40:
For shell scripting purposes, [http://netcat.sf.net netcat] also works well.
For shell scripting purposes, [http://netcat.sf.net netcat] also works well.


The routines already support network byte order, however there are cases (i.e. interfacing to an external perl script using pack/unpack, where network byte order is not desirable).
The routines already support network byte order, however there are cases (i.e. interfacing to an external Perl script using pack/unpack, where network byte order is not desirable).


In comparison to the binary native protocol, the props/telnet protocol is a lower bandwidth, high reliablity channel. You are guaranteed that every message gets to the receiver once (and only once.) This is great for setting up weather conditions, time of day, camera parameters, and anything else that might have an impact on the visuals. We have a convenient "telnet" interface to all the internal properties and built in commands. Anything you can set from the keyboard, or mouse, or gui, you can do from a remote program or script. It's much lower bandwidth, but very convenient.
In comparison to the binary native protocol, the props/telnet protocol is a lower bandwidth, high reliability channel. You are guaranteed that every message gets to the receiver once (and only once.) This is great for setting up weather conditions, time of day, camera parameters, and anything else that might have an impact on the visuals. We have a convenient "telnet" interface to all the internal properties and built in commands. Anything you can set from the keyboard, or mouse, or GUI, you can do from a remote program or script. It's much lower bandwidth, but very convenient.


The telnet mechanism is not designed to be high bandwidth.  I believe it runs at 5hz? and only processes one line/command per iteration. You could try upping the frequency via the command line, "--props=socket,bi,20,,5500,tcp" (we could change PropsChannel::foundTerminator() to handle several
The telnet mechanism is not designed to be high bandwidth.  I believe it runs at 5hz? and only processes one line/command per iteration. You could try upping the frequency via the command line, "--props=socket,bi,20,,5500,tcp" (we could change PropsChannel::foundTerminator() to handle several
Line 62: Line 62:
</pre>
</pre>


TCP sockets are easier to implement for almost all applications, precicely because they are reliable.  UDP will only look easier if you plan on skipping the code to recover from a lost packet.  Some applications can do this, but the property tree can't -- property access is non-idempotent in the general case. Listeners can have side effects.
TCP sockets are easier to implement for almost all applications, precisely because they are reliable.  UDP will only look easier if you plan on skipping the code to recover from a lost packet.  Some applications can do this, but the property tree can't -- property access is non-idempotent in the general case. Listeners can have side effects.


== Telnet Server ==
== Telnet Server ==
Line 72: Line 72:


== Starting FlightGear with Telnet Server ==
== Starting FlightGear with Telnet Server ==
(Note if you want to use an SSH client like putty, you'll need to disable the SSH mode, FG does NOT support SSH, it only supports the raw telnet mode!)
(Note if you want to use an SSH client like putty, you'll need to disable the SSH mode, FlightGear does NOT support SSH, it only supports the raw telnet mode!)


Now, start up FlightGear with the following option: --telnet=5401 (or pick your favorite port number) Once FlightGear is up and running, go to an xterm/shell on the same machine running flightgear and type "telnet localhost 5401". You could do this from any machine on the net by substituting the appropriate machine name/ip-address. From the telnet session hit enter or type "help" to get a list of available commands. You can now remotely navigate through the property structure and examine and change values in the live running copy of FlightGear. This is very powerful (although low bandwidth) and allows you to set and change a huge range of values in FlightGear.
Now, start up FlightGear with the following option: --telnet=5401 (or pick your favorite port number) Once FlightGear is up and running, go to an xterm/shell on the same machine running FlightGear and type "telnet localhost 5401". You could do this from any machine on the net by substituting the appropriate machine name/IP-address. From the telnet session hit enter or type "help" to get a list of available commands. You can now remotely navigate through the property structure and examine and change values in the live running copy of FlightGear. This is very powerful (although low bandwidth) and allows you to set and change a huge range of values in FlightGear.


Even better, it's pretty easy to automate a remote telnet session so you can write scripts or code that can remotely control FlightGear in various ways. I've written a commercial operator GUI that interfaces to FlightGear in this way. I've scripted (perl) out all the FAA Level 3 FTD certification tests in this way (setting up initial conditions, reseting the FDM, enabling/adjusting autopilot modes, and even remotely manipulating control surfaces when needed.)
Even better, it's pretty easy to automate a remote telnet session so you can write scripts or code that can remotely control FlightGear in various ways. I've written a commercial operator GUI that interfaces to FlightGear in this way. I've scripted (Perl) out all the FAA Level 3 FTD certification tests in this way (setting up initial conditions, resetting the FDM, enabling/adjusting autopilot modes, and even remotely manipulating control surfaces when needed.)


And you can use the same mechanism to adjust view parameters, configure weather settings, time of day, etc.
And you can use the same mechanism to adjust view parameters, configure weather settings, time of day, etc.
Line 82: Line 82:
The only draw back is that it's low bandwidth. It's good for setting a few parameters at a relatively low rate, it's good for interactive use, it's good for many remote scripting tasks, but you don't want to use it to try to blast a bunch of position/orientation data in real time. We have other interfaces better suited for that.
The only draw back is that it's low bandwidth. It's good for setting a few parameters at a relatively low rate, it's good for interactive use, it's good for many remote scripting tasks, but you don't want to use it to try to blast a bunch of position/orientation data in real time. We have other interfaces better suited for that.


I should also point out that we have an html version of the telnet interface "--httpd=5400" that allows you to connect up to a live copy of FlightGear from any web browser and interact with the sim. Just type in a url like this: "http://localhost:5401/";
I should also point out that we have an html version of the telnet interface "--httpd=5400" that allows you to connect up to a live copy of FlightGear from any web browser and interact with the sim. Just type in a URL like this: "http://localhost:5401/";


== Connect with Telnet Client ==
== Connect with Telnet Client ==
Once connected to the server using a telnet client, you will be given a prompt such as if you where connected to a unix telnet server, example:
Once connected to the server using a telnet client, you will be given a prompt such as if you where connected to a Unix telnet server, example:
<pre>
<pre>
francesco@francesco-desktop:~$ telnet 127.0.0.1 5401
francesco@francesco-desktop:~$ telnet 127.0.0.1 5401
Line 142: Line 142:


=== data ===
=== data ===
Switch to data mode. This removes the '''prompt/>'''. This is mostly useful when communicating from code, eg a socket.  
Switch to data mode. This removes the '''prompt/>'''. This is mostly useful when communicating from code, e.g. a socket.  


To switch back on see prompt below.
To switch back on see prompt below.
Line 174: Line 174:
  />
  />


Usually, you'd use "polling" to continuously update a property via "get" - however, as of FG 2.8 there are two new commands supported, see [[Telnet usage#subscribe and unsubscribe]].
Usually, you'd use "polling" to continuously update a property via "get" - however, as of FlightGear 2.8 there are two new commands supported, see [[Telnet usage#subscribe and unsubscribe]].


=== help ===
=== help ===
Line 199: Line 199:


=== pwd ===
=== pwd ===
Display the current directory ie print working directory
Display the current directory i.e. print working directory


=== quit ===
=== quit ===
Line 272: Line 272:


}}
}}
You'll find two new telnet commands in FG >= 2.8 that provide a very simple "subscription" mechanism, so that you can register listeners instead of using polling to get property updates.  
You'll find two new telnet commands in FlightGear >= 2.8 that provide a very simple "subscription" mechanism, so that you can register listeners instead of using polling to get property updates.  
Obviously, that makes only sense for non-FDM (non-tied) properties and properties that are not updated at frame rate.  
Obviously, that makes only sense for non-FDM (non-tied) properties and properties that are not updated at frame rate.  
But otherwise it can save you some bandwidth and prevent unnecessary polling:
But otherwise it can save you some bandwidth and prevent unnecessary polling:
Line 304: Line 304:


== Interfacing with other programs ==
== Interfacing with other programs ==
Using the telnet interface, your own custom client software can request the value of any variable at any time. You can also update the value of any other variable at any time. The overall bandwidth of the telnet interface is not very high though so it's not appropriate for blasting all the flight dynamics data at 60hz for instance, but for your application it probably will work very well ... and I can imagine ways to cheat that would make it look like it was working even better than it actually was. (For instance, you might get some delay if you turn the knob, send the data to FG, and then read the new frequency back from FG, but if you know locally how far your knob turned, you can update your local display immediately, and then sync up with FG at a slower rate.)
Using the telnet interface, your own custom client software can request the value of any variable at any time. You can also update the value of any other variable at any time. The overall bandwidth of the telnet interface is not very high though so it's not appropriate for blasting all the flight dynamics data at 60hz for instance, but for your application it probably will work very well ... and I can imagine ways to cheat that would make it look like it was working even better than it actually was. (For instance, you might get some delay if you turn the knob, send the data to FlightGear, and then read the new frequency back from FlightGear, but if you know locally how far your knob turned, you can update your local display immediately, and then sync up with FlightGear at a slower rate.)


The cool thing is that you can easily write scripts to access the --telnet=<port#> interface.
The cool thing is that you can easily write scripts to access the --telnet=<port#> interface.
Line 316: Line 316:
Look under src/scripts and you'll find example code showing you how to do it  in Python, Perl and C. The Python/Java ones includes a FlightGear module that makes the telnet part pretty transparent.
Look under src/scripts and you'll find example code showing you how to do it  in Python, Perl and C. The Python/Java ones includes a FlightGear module that makes the telnet part pretty transparent.


There are a couple examples in the scripts section of the FG source code. There is a chunk of perl (telnet.pl) you can include to make access from a perl script mostly trivial. I think there is a java example and perhaps something for python.
There are a couple examples in the scripts section of the FlightGear source code. There is a chunk of Perl (telnet.pl) you can include to make access from a Perl script mostly trivial. I think there is a Java example and perhaps something for Python.


You should have a look at fgfsclient.cxx in the FG/script/exmaple subtree (on the cvs). The script/python subtree has also good examples
You should have a look at fgfsclient.cxx in the FG/script/exmaple subtree (on the CVS). The script/python subtree has also good examples
of what can be done using the telnet protocol. The server side of the "telnet" protocol can be found in the src/Network/props.* files.
of what can be done using the telnet protocol. The server side of the "telnet" protocol can be found in the src/Network/props.* files.
Also FG must be lauched with --props=5501 to activate the server side.
Also FG must be lauched with --props=5501 to activate the server side.
Line 328: Line 328:
* Java - {{flightgear source|path=scripts/java}}
* Java - {{flightgear source|path=scripts/java}}


You could just as easily interact with a running FlightGear instance using perl, C, C++, java, python, probably even <ack> visual basic or anything else that can do TCP/IP network communication ... matlab? netcat? twisted?
You could just as easily interact with a running FlightGear instance using Perl, C, C++, Java, Python, probably even <ACK> visual basic or anything else that can do TCP/IP network communication ... MatLab? netcat? twisted?


Also note that the downside to the telnet interface is that you can't blast a lot of data across it. It's fine if you want to monitor location and speed every second or 1/4 second and occasionally set some values; such as dump in a new weather configuration, reset the aircraft location, or read a set of values, etc.
Also note that the downside to the telnet interface is that you can't blast a lot of data across it. It's fine if you want to monitor location and speed every second or 1/4 second and occasionally set some values; such as dump in a new weather configuration, reset the aircraft location, or read a set of values, etc.
Line 382: Line 382:
</pre>
</pre>


To start on a 5 mile final to runway KBUR, runway 08 at 90 kts (3
To start on a 5 mile final to runway KBUR, runway 08 at 90 kt (glide slope) you could do something like:
degree glide slope) you could do something like:


<pre>
<pre>
Line 407: Line 406:
</pre>
</pre>


To start over some fix (DAVID for instance) :-) at an alitude of 5000', airspeed of 90 kts, and heading of 45 degrees:
To start over some fix (DAVID for instance) :-) at an altitude of 5000 ft, airspeed of 90 kt, and heading of 45°:


<pre>
<pre>
Line 434: Line 433:


== Use Case: Autopilot & Route Manager ==
== Use Case: Autopilot & Route Manager ==
The autopilotss (there are several different implementations) are part of the models. (Rationale is that autopilot devices normally are mounted *in* the
The autopilots (there are several different implementations) are part of the models. (Rationale is that autopilot devices normally are mounted *in* the
aircrafts in the real world =). If you are developing your own stand-alone autopilot and want it on another host, there are several ways to interface
aircraft in the real world =). If you are developing your own stand-alone autopilot and want it on another host, there are several ways to interface
to the simulator to control the aircraft remotely.
to the simulator to control the aircraft remotely.


Line 441: Line 440:


The simplest way to /set/ a property is perhaps via the telnet interface. fgfs --telnet=<port> then do "telnet <host> <port>" and type "help" to see
The simplest way to /set/ a property is perhaps via the telnet interface. fgfs --telnet=<port> then do "telnet <host> <port>" and type "help" to see
the syntax. You can read properties aswell, that way, but perhaps you rather prefer to get data synchronously. This can be achieved through the
the syntax. You can read properties as well, that way, but perhaps you rather prefer to get data synchronously. This can be achieved through the
general i/o-interface.
general i/o-interface.


Regarding the autopilot, I believe you have to set the target speed value and then activate that particular autopilot mode, so you need to actually set two values.  You should be able to look in the autopilot gui to see the exact property names (I don't have them here off the top of my head.) And watch out for spelling: that's one thing I've learned to check when things don't work as expected.  With properties, the compiler can't spell check variable names at compile time so typos can creep in.  When something doesn't behave as expected, it's worth looking in the property tree while the code is running to see if any new properties (with similar, but not quite exact spellings) have appeared.  
Regarding the autopilot, I believe you have to set the target speed value and then activate that particular autopilot mode, so you need to actually set two values.  You should be able to look in the autopilot GUI to see the exact property names (I don't have them here off the top of my head.) And watch out for spelling: that's one thing I've learned to check when things don't work as expected.  With properties, the compiler can't spell check variable names at compile time so typos can creep in.  When something doesn't behave as expected, it's worth looking in the property tree while the code is running to see if any new properties (with similar, but not quite exact spellings) have appeared.  


At a lower level, the FlightGear waypoint system (route manager) can handle any arbitrary latitude and longitude and altitude.  However, something that might work better for you (?) would be to just set up a basic autopilot that can hold a commanded heading, altitude, speed, etc. and then monitor the flight location from the remote search algorithm and pass heading updates to the autopilot.
At a lower level, the FlightGear waypoint system (route manager) can handle any arbitrary latitude and longitude and altitude.  However, something that might work better for you (?) would be to just set up a basic autopilot that can hold a commanded heading, altitude, speed, etc. and then monitor the flight location from the remote search algorithm and pass heading updates to the autopilot.
Line 480: Line 479:


== Use Case: Radio Stack ==
== Use Case: Radio Stack ==
For the easiest start, I'd use a single fg instance, with the telnet server enabled, and write a little (eg. perl) script that reads the parallel port where you have your switch connected, and changes a property via the telnet interface when the switch gets opened/closed. If you'd like to build a hardware radio stack and interface it to FG. There are a couple of ways you could attack this.
For the easiest start, I'd use a single fg instance, with the telnet server enabled, and write a little (e.g. Perl) script that reads the parallel port where you have your switch connected, and changes a property via the telnet interface when the switch gets opened/closed. If you'd like to build a hardware radio stack and interface it to FlightGear. There are a couple of ways you could attack this.


* Add a module (i.e. some code) inside FG that runs every frame. Your code would read all your hardware switches through whatever mechanism you have devised and update the FG internals. It would also send things like frequencies (probably cooked up in the best flavor for your hardware) so that the radio stack can display the frequencies.
* Add a module (i.e. some code) inside FlightGear that runs every frame. Your code would read all your hardware switches through whatever mechanism you have devised and update the FG internals. It would also send things like frequencies (probably cooked up in the best flavor for your hardware) so that the radio stack can display the frequencies.


* You could go for total separation and create an external application that talks directly to your hardware. That application could then communicate with FG via the "telnet" interface to read the necessary FG property values to update your hardware display, and write the switch/knob values back to FG as input to it's radio models.
* You could go for total separation and create an external application that talks directly to your hardware. That application could then communicate with FlightGear via the "telnet" interface to read the necessary FlightGear property values to update your hardware display, and write the switch/knob values back to FlightGearas input to it's radio models.


There are probably a variety of other ways you could get this done, but these two approaches are the ones that jump to the front of my list. The first approach would require a bit more digging into the FG internals, the 2nd approach could have potentially sluggish performance. The "telnet" interface is the ultimate in flexibility, but is not anywhere close to high bandwidth.
There are probably a variety of other ways you could get this done, but these two approaches are the ones that jump to the front of my list. The first approach would require a bit more digging into the FlightGear internals, the 2nd approach could have potentially sluggish performance. The "telnet" interface is the ultimate in flexibility, but is not anywhere close to high bandwidth.
 
== Links ==
* httpd source - {{flightgear source|path=src/Network/http/httpd.cxx}}
* telnet (props) source - {{flightgear source|path=src/Network/props.cxx}}


== Related content ==
=== Source code ===
* {{flightgear source|path=src/Network/http/httpd.cxx}} - httpd
* {{flightgear source|path=src/Network/props.cxx}} -telnet (props)


[[Category:Interfacing protocols]]
[[Category:Interfacing protocols]]