The FlightGear flight simulator is an open-source, multi-platform, cooperative flight simulator developed as a part of the FlightGear project. I have been using this Flight simulator for a year for Virtual Flight testing, running simulations and measuring flight parameters during various types of maneuvers. I have noticed that, logging the data, (figuring out how to log in the first place) has been quite difficult for users with less technical knowledge in such softwares.
Also, the Property Tree of FlightGear is pretty extensive making it difficult to properly traverse the huge tree to get the parameters that are actually required.
That's when I got the idea of making a simple, easy to use, user friendly logging interface for FlightGear. I gave it a name 'FlightGear Command Center' :wink: and the project was born at github.com/niranjan94/flightgear-cc.
After 44 commits, this is what I have now.
1. A simple dashboard to connect to FlightGear, open FlightGear with a default plane, Getting individual parameter values or to log a lot of parameters continuously
2. An interface to choose the parameters to log and the interval
- The Web application communicates with a python bridge using WebSockets.
- The python bridge communicates with FlightGear via telnet.
- The data is logged to a csv file continuously (until the user presses stop) by the bridge once the web application requests it.
The interface with FlightGear
FlightGear has an internal "telnet" command server which provides us "remote shell" into the running FlightGear process which we can exploit to interactively view or modify any property/variable of the simulation.
FlightGear can be instructed to start the server and listen for commands by passing the
--telnet=socket,out,60,localhost,5555,udp command line argument while starting FlightGear. (The argument is of format
Communication with that server can be done using any simple telnet interface. But FlightGear also provides us with a small wrapper class that makes retrieving and setting properties using the telnet server even more easier.
The wrapper can be obtained from the official repository at sourceforge.net/p/flightgear/flightgear/ci/master/tree/scripts/python/FlightGear.py
Using the wrapper is straightforward. Initialize an instance of the class with the hostname and port. The class will then make a connection to the telnet server.
from FlightGear import FlightGear flightgear_server = 'localhost' flightgear_server_port = 5555 fg = FlightGear(flightgear_server, flightgear_server_port)
The wrapper makes use of python's magic methods
__getitem__ to make it easy for us to read or manipulate the property tree.
For example, getting the current altitude of the airplane is as easy as
and setting the altitude is as simple as
fg['/position/altitude-ft'] = 345.2
But the important thing here is, knowing the path to the data you want in the FlightGear property tree. Most of the commonly used properties are available over at Aircraft properties reference - FlightGear Wiki.
Now that we have basic interface between python and FlightGear in place, the next step would be to setup a link between the user interface (a small web app) and the python bridge. We would be using WebSockets for that so as to have a Real-time and an always on link to the bridge which would enable us to in turn communicate with FlightGear in realtime.
A websocket server can be created by,
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket hostname = 'localhost' websocket_server_port = 8888 class SocketHandler(WebSocket): def handleMessage(self): # print the message when received print self.data def handleConnected(self): print self.address, 'connected' def handleClose(self): print self.address, 'closed' server = SimpleWebSocketServer(hostname, websocket_server_port, SocketHandler) server.serveforever()
handleMessageis called whenever a client sends a message to the server
handleConnectedis called when a new client connects to the server
handleCloseis called when a client disconnects from the server
A message can be sent to the clients by using the
sendMessage method from within the
class SocketHandler(WebSocket): def handleMessage(self): # send a hello whenever a message is received print self.data self.sendMessage('Hello') def handleConnected(self): print self.address, 'connected' def handleClose(self): print self.address, 'closed'