diff --git a/FlightGear.dsp b/FlightGear.dsp index 5de11a36a..770a290f8 100644 --- a/FlightGear.dsp +++ b/FlightGear.dsp @@ -35,13 +35,13 @@ RSC=rc.exe # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # 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 # ADD RSC /l 0xc09 /d "NDEBUG" BSC32=bscmake.exe # ADD BSC32 /nologo 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" @@ -51,12 +51,12 @@ LINK32=link.exe # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # 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" BSC32=bscmake.exe # ADD BSC32 /nologo 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 @@ -1099,6 +1099,36 @@ SOURCE=.\src\Environment\environment_mgr.hxx !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 Group # Begin Group "Lib_Balloon" @@ -5660,6 +5690,36 @@ SOURCE=.\src\FDM\MagicCarpet.hxx # End 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 !IF "$(CFG)" == "FlightGear - Win32 Release" @@ -8283,7 +8343,6 @@ SOURCE=.\src\WeatherCM\sphrintp.h # End Source File # End Group - # Begin Source File SOURCE = .\src\Include\config.h-msvc6 @@ -8293,7 +8352,7 @@ SOURCE = .\src\Include\config.h-msvc6 # Begin Custom Build - Creating config.h InputPath=.\src\Include\config.h-msvc6 -".\src\Include\config.h": $(SOURCE) "$(INTDIR)" "$(OUTDIR)" +".\src\Include\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy .\src\Include\config.h-msvc6 .\src\Include\config.h # End Custom Build @@ -8303,7 +8362,7 @@ InputPath=.\src\Include\config.h-msvc6 # Begin Custom Build - Creating config.h InputPath=.\src\Include\config.h-msvc6 -".\src\Include\config.h": $(SOURCE) "$(INTDIR)" "$(OUTDIR)" +".\src\Include\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy .\src\Include\config.h-msvc6 .\src\Include\config.h # End Custom Build diff --git a/Makefile.am b/Makefile.am index 0fd21ccc0..becafbca4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,8 @@ SUBDIRS = \ tests \ - man \ - src + src \ + scripts \ + man EXTRA_DIST = Thanks acsite.m4 acconfig.h irix-hack.sh \ FlightGear.dsp FlightGear.dsw diff --git a/scripts/Makefile.am b/scripts/Makefile.am new file mode 100644 index 000000000..96fcb3e25 --- /dev/null +++ b/scripts/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = python diff --git a/scripts/python/FlightGear.py b/scripts/python/FlightGear.py new file mode 100644 index 000000000..ec28425e4 --- /dev/null +++ b/scripts/python/FlightGear.py @@ -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) diff --git a/scripts/python/Makefile.am b/scripts/python/Makefile.am new file mode 100644 index 000000000..aa0d9abc6 --- /dev/null +++ b/scripts/python/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = FlightGear.py demo.py diff --git a/scripts/python/demo.py b/scripts/python/demo.py new file mode 100644 index 000000000..8f32c8232 --- /dev/null +++ b/scripts/python/demo.py @@ -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()