Added a scripts subdirectory with support for running external python
scripts that communicate with FlightGear via it's "telnet" interface.
This commit is contained in:
parent
f9f05aa870
commit
f69a1c8f66
6 changed files with 270 additions and 9 deletions
|
@ -35,13 +35,13 @@ RSC=rc.exe
|
||||||
# PROP Output_Dir "Release"
|
# PROP Output_Dir "Release"
|
||||||
# PROP Intermediate_Dir "Release"
|
# PROP Intermediate_Dir "Release"
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD CPP /nologo /W3 /GX /O2 /D "HAVE_CONFIG_H" /I ".." /I ".\src" /I ".\src\include" /I "..\SimGear" /I "..\SimGear\simgear\metakit\include" /D "FGFS" /D "HAVE_CONFIG_H" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /c
|
# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /c /MTd /I ".." /I ".\src" /I ".\src\include" /I "..\SimGear" /I "..\SimGear\metakit-2.4.3\include" /I "..\SimGear\zlib-1.1.4" /D "HAVE_CONFIG_H" /D "FGFS" /D "FG_NEW_ENVIRONMENT" /D "ENABLE_AUDIO_SUPPORT" /D "ENABLE_PLIB_JOYSTICK"
|
||||||
# SUBTRACT CPP /YX
|
# SUBTRACT CPP /YX
|
||||||
# ADD RSC /l 0xc09 /d "NDEBUG"
|
# ADD RSC /l 0xc09 /d "NDEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\plib" ssg.lib sg.lib pui.lib fnt.lib sl.lib ul.lib ssgaux.lib net.lib /libpath:"..\SimGear" SimGear.lib /libpath:"..\SimGear\simgear\metakit\builds" mk4vc60s_d.lib
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "FlightGear - Win32 Debug"
|
!ELSEIF "$(CFG)" == "FlightGear - Win32 Debug"
|
||||||
|
|
||||||
|
@ -51,12 +51,12 @@ LINK32=link.exe
|
||||||
# PROP Intermediate_Dir "Debug"
|
# PROP Intermediate_Dir "Debug"
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c /D "HAVE_CONFIG_H" /I ".." /I ".\src" /I ".\src\include" /I "..\SimGear" /I "..\SimGear\simgear\metakit\include" /D "FGFS" /D "HAVE_CONFIG_H"
|
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c /MTd /I ".." /I ".\src" /I ".\src\include" /I "..\SimGear" /I "..\SimGear\metakit-2.4.3\include" /I "..\SimGear\zlib-1.1.4" /D "HAVE_CONFIG_H" /D "FGFS" /D "FG_NEW_ENVIRONMENT" /D "ENABLE_AUDIO_SUPPORT" /D "ENABLE_PLIB_JOYSTICK"
|
||||||
# ADD RSC /l 0xc09 /d "_DEBUG"
|
# ADD RSC /l 0xc09 /d "_DEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD LINK32 kernel32.lib user32.lib winspool.lib comdlg32.lib gdi32.lib shell32.lib glut32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\plib" ssg.lib sg.lib pui.lib fnt.lib sl.lib ul.lib ssgaux.lib net.lib /libpath:"..\SimGear" SimGear.lib /libpath:"..\SimGear\simgear\metakit\builds" mk4vc60s_d.lib"
|
# ADD LINK32 kernel32.lib user32.lib winspool.lib comdlg32.lib gdi32.lib shell32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
@ -1099,6 +1099,36 @@ SOURCE=.\src\Environment\environment_mgr.hxx
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\Environment\environment_ctrl.cxx
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "FlightGear - Win32 Release"
|
||||||
|
|
||||||
|
# PROP Intermediate_Dir "Release\Lib_Environment"
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "FlightGear - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP Intermediate_Dir "Debug\Lib_Environment"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\Environment\environment_ctrl.hxx
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "FlightGear - Win32 Release"
|
||||||
|
|
||||||
|
# PROP Intermediate_Dir "Release\Lib_Environment"
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "FlightGear - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP Intermediate_Dir "Debug\Lib_Environment"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "Lib_Balloon"
|
# Begin Group "Lib_Balloon"
|
||||||
|
@ -5660,6 +5690,36 @@ SOURCE=.\src\FDM\MagicCarpet.hxx
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\FDM\UFO.cxx
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "FlightGear - Win32 Release"
|
||||||
|
|
||||||
|
# PROP Intermediate_Dir "Release\Lib_Flight"
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "FlightGear - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP Intermediate_Dir "Debug\Lib_Flight"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\FDM\UFO.hxx
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "FlightGear - Win32 Release"
|
||||||
|
|
||||||
|
# PROP Intermediate_Dir "Release\Lib_Flight"
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "FlightGear - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP Intermediate_Dir "Debug\Lib_Flight"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\src\FDM\NullFDM.cxx
|
SOURCE=.\src\FDM\NullFDM.cxx
|
||||||
|
|
||||||
!IF "$(CFG)" == "FlightGear - Win32 Release"
|
!IF "$(CFG)" == "FlightGear - Win32 Release"
|
||||||
|
@ -8283,7 +8343,6 @@ SOURCE=.\src\WeatherCM\sphrintp.h
|
||||||
|
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
|
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE = .\src\Include\config.h-msvc6
|
SOURCE = .\src\Include\config.h-msvc6
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
tests \
|
tests \
|
||||||
man \
|
src \
|
||||||
src
|
scripts \
|
||||||
|
man
|
||||||
|
|
||||||
EXTRA_DIST = Thanks acsite.m4 acconfig.h irix-hack.sh \
|
EXTRA_DIST = Thanks acsite.m4 acconfig.h irix-hack.sh \
|
||||||
FlightGear.dsp FlightGear.dsw
|
FlightGear.dsp FlightGear.dsw
|
||||||
|
|
1
scripts/Makefile.am
Normal file
1
scripts/Makefile.am
Normal file
|
@ -0,0 +1 @@
|
||||||
|
SUBDIRS = python
|
157
scripts/python/FlightGear.py
Normal file
157
scripts/python/FlightGear.py
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
from telnetlib import Telnet
|
||||||
|
import sys
|
||||||
|
import socket
|
||||||
|
import re
|
||||||
|
from string import split, join
|
||||||
|
import time
|
||||||
|
|
||||||
|
__all__ = ["FlightGear"]
|
||||||
|
|
||||||
|
CRLF = '\r\n'
|
||||||
|
|
||||||
|
class FGTelnet(Telnet):
|
||||||
|
def __init__(self,host,port):
|
||||||
|
Telnet.__init__(self,host,port)
|
||||||
|
self.prompt = []
|
||||||
|
self.prompt.append( re.compile('/[^>]*> ') )
|
||||||
|
self.timeout = 5
|
||||||
|
#Telnet.set_debuglevel(self,2)
|
||||||
|
|
||||||
|
def help(self):
|
||||||
|
return
|
||||||
|
|
||||||
|
def ls(self,dir=None):
|
||||||
|
"""
|
||||||
|
Returns a list of properties.
|
||||||
|
"""
|
||||||
|
if dir == None:
|
||||||
|
self._putcmd('ls')
|
||||||
|
else:
|
||||||
|
self._putcmd('ls %s' % dir )
|
||||||
|
return self._getresp()
|
||||||
|
|
||||||
|
def dump(self):
|
||||||
|
"""Dump current state as XML."""
|
||||||
|
self._putcmd('dump')
|
||||||
|
return self._getresp()
|
||||||
|
|
||||||
|
def cd(self, dir):
|
||||||
|
"""Change directory."""
|
||||||
|
self._putcmd('cd ' + dir)
|
||||||
|
self._getresp()
|
||||||
|
return
|
||||||
|
|
||||||
|
def pwd(self):
|
||||||
|
"""Display current path."""
|
||||||
|
self._putcmd('pwd')
|
||||||
|
return self._getresp()
|
||||||
|
|
||||||
|
def get(self,var):
|
||||||
|
"""Retrieve the value of a parameter."""
|
||||||
|
self._putcmd('get %s' % var )
|
||||||
|
return self._getresp()
|
||||||
|
|
||||||
|
def set(self,var,value):
|
||||||
|
"""Set variable to a new value"""
|
||||||
|
self._putcmd('set %s %s' % (var,value))
|
||||||
|
self._getresp() # Discard response
|
||||||
|
|
||||||
|
def quit(self):
|
||||||
|
"""Terminate connection"""
|
||||||
|
self._putcmd('quit')
|
||||||
|
self.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
# Internal: send one command to FlightGear
|
||||||
|
def _putcmd(self,cmd):
|
||||||
|
cmd = cmd + CRLF;
|
||||||
|
Telnet.write(self, cmd)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Internal: get a response from FlightGear
|
||||||
|
def _getresp(self):
|
||||||
|
(i,match,resp) = Telnet.expect(self, self.prompt, self.timeout)
|
||||||
|
# Remove the terminating prompt.
|
||||||
|
# Everything preceding it is the response.
|
||||||
|
return split(resp, '\n')[:-1]
|
||||||
|
|
||||||
|
class FlightGear:
|
||||||
|
"""FlightGear interface class.
|
||||||
|
|
||||||
|
An instance of this class represents a connection to a FlightGear telnet
|
||||||
|
server.
|
||||||
|
|
||||||
|
Properties are accessed using a dictionary style interface:
|
||||||
|
For example:
|
||||||
|
|
||||||
|
# Connect to flightgear telnet server.
|
||||||
|
fg = FlightGear('myhost', 5500)
|
||||||
|
# parking brake on
|
||||||
|
fg['/controls/parking-brake'] = 1
|
||||||
|
# Get current heading
|
||||||
|
heading = fg['/orientation/heading-deg']
|
||||||
|
|
||||||
|
Other non-property related methods
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__( self, host = 'localhost', port = 5500 ):
|
||||||
|
try:
|
||||||
|
self.telnet = FGTelnet(host,port)
|
||||||
|
except socket.error, msg:
|
||||||
|
self.telnet = None
|
||||||
|
raise socket.error, msg
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
# Ensure telnet connection is closed cleanly.
|
||||||
|
self.quit();
|
||||||
|
|
||||||
|
def __getitem__(self,key):
|
||||||
|
"""Get a FlightGear property value.
|
||||||
|
Where possible the value is converted to the equivalent Python type.
|
||||||
|
"""
|
||||||
|
s = self.telnet.get(key)[0]
|
||||||
|
(name,x,value,type) = s.split()
|
||||||
|
if value == '':
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
value = value[1:-1] # strip quote characters
|
||||||
|
#print "name=%s,value=%s,type=%s" % (name,value,type)
|
||||||
|
if type == '(double)':
|
||||||
|
return float(value)
|
||||||
|
elif type == '(int)':
|
||||||
|
return int(value)
|
||||||
|
elif type == '(bool)':
|
||||||
|
if value == 'true':
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
"""Set a FlightGear property value.
|
||||||
|
"""
|
||||||
|
self.telnet.set( key, value )
|
||||||
|
|
||||||
|
def quit(self):
|
||||||
|
"""Close the telnet connection to FlightGear.
|
||||||
|
"""
|
||||||
|
if self.telnet:
|
||||||
|
self.telnet.quit()
|
||||||
|
self.telnet = None
|
||||||
|
|
||||||
|
def view_next(self):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
self.telnet._putcmd('view next')
|
||||||
|
self.telnet._getresp()
|
||||||
|
|
||||||
|
def view_prev(self):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
self.telnet._putcmd('view prev')
|
||||||
|
self.telnet._getresp()
|
||||||
|
|
||||||
|
def wait_for_prop_eq(self, prop, value, interval = 0.5):
|
||||||
|
while self.__getitem__(prop) != value:
|
||||||
|
time.sleep(interval)
|
1
scripts/python/Makefile.am
Normal file
1
scripts/python/Makefile.am
Normal file
|
@ -0,0 +1 @@
|
||||||
|
EXTRA_DIST = FlightGear.py demo.py
|
42
scripts/python/demo.py
Normal file
42
scripts/python/demo.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
from FlightGear import FlightGear
|
||||||
|
import time
|
||||||
|
|
||||||
|
def main():
|
||||||
|
fg = FlightGear('localhost', 5500)
|
||||||
|
|
||||||
|
# Wait five seconds for simulator to settle down
|
||||||
|
while fg['/sim/time/elapsed-ms'] < 5000:
|
||||||
|
time.sleep(1.0)
|
||||||
|
|
||||||
|
# parking brake on
|
||||||
|
fg['/controls/parking-brake'] = 1
|
||||||
|
|
||||||
|
heading = fg['/orientation/heading-deg']
|
||||||
|
|
||||||
|
# Switch to external view for for 'walk around'.
|
||||||
|
fg.view_next()
|
||||||
|
|
||||||
|
fg['/sim/current-view/goal-heading-offset-deg'] = 180.0
|
||||||
|
fg.wait_for_prop_eq('/sim/current-view/heading-offset-deg', 180.0)
|
||||||
|
|
||||||
|
fg['/sim/current-view/goal-heading-offset-deg'] = 90.0
|
||||||
|
fg.wait_for_prop_eq('/sim/current-view/heading-offset-deg', 90.0)
|
||||||
|
|
||||||
|
fg['/sim/current-view/goal-heading-offset-deg'] = 0.0
|
||||||
|
fg.wait_for_prop_eq('/sim/current-view/heading-offset-deg', 0.0)
|
||||||
|
|
||||||
|
time.sleep(2.0)
|
||||||
|
|
||||||
|
# Switch back to cockpit view
|
||||||
|
fg.view_prev()
|
||||||
|
|
||||||
|
time.sleep(2.0)
|
||||||
|
|
||||||
|
# Flaps to take off position
|
||||||
|
fg['/controls/flaps'] = 0.34
|
||||||
|
fg.wait_for_prop_eq('/surface-positions/flap-pos-norm', 0.34)
|
||||||
|
|
||||||
|
fg.quit()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in a new issue