diff --git a/Makefile.am b/Makefile.am
index e9ccc708020f73e27ef341c48eb44047e8554415..7ea801f9da3706bfa704c6844d168557d6070e1d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS	= src systems aircraft engine scripts data_output data_plot check_cases
+SUBDIRS	= src gui systems aircraft engine scripts data_output data_plot check_cases
 
 dist-hook:
 	(cd $(top_srcdir))
diff --git a/autotroll.m4 b/autotroll.m4
new file mode 100644
index 0000000000000000000000000000000000000000..5037197527cfef414c13ea8c81413a3ef86ceab8
--- /dev/null
+++ b/autotroll.m4
@@ -0,0 +1,565 @@
+# Build Qt apps with the autotools (Autoconf/Automake).
+# M4 macros.
+# This file is part of AutoTroll.
+# Copyright (C) 2006  Benoit Sigoure <benoit.sigoure@lrde.epita.fr>
+#
+# AutoTroll is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+#
+# In addition, as a special exception, the copyright holders of AutoTroll
+# give you unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the macros of
+# AutoTroll.  You need not follow the terms of the GNU General Public License
+# when using or distributing such scripts, even though portions of the text of
+# AutoTroll appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes AutoTroll.
+#
+# This special exception to the GPL applies to versions of AutoTroll
+# released by the copyright holders of AutoTroll.  Note that people who make
+# modified versions of AutoTroll are not obligated to grant this special
+# exception for their modified versions; it is their choice whether to do so.
+# The GNU General Public License gives permission to release a modified version
+# without this exception; this exception also makes it possible to release a
+# modified version which carries forward this exception.
+
+ # ------------- #
+ # DOCUMENTATION #
+ # ------------- #
+
+# Disclaimer: Never tested with anything else than Qt 4.2! Feedback welcome.
+# Simply invoke AT_WITH_QT in your configure.ac. AT_WITH_QT can take
+# arguments which are documented in depth below. The default arguments are
+# equivalent to the default .pro file generated by qmake.
+#
+# Invoking AT_WITH_QT will do the following:
+#  - Add a --with-qt option to your configure
+#  - Find qmake, moc and uic and save them in the make variables $(QMAKE),
+#    $(MOC), $(UIC).
+#  - Save the path to Qt in $(QT_PATH)
+#  - Find the flags to use Qt, that is:
+#     * $(QT_DEFINES): -D's defined by qmake.
+#     * $(QT_CFLAGS): CFLAGS as defined by qmake (C?!)
+#     * $(QT_CXXFLAGS): CXXFLAGS as defined by qmake.
+#     * $(QT_INCPATH): -I's defined by qmake.
+#     * $(QT_CPPFLAGS): Same as $(QT_DEFINES) + $(QT_INCPATH)
+#     * $(QT_LFLAGS): LFLAGS defined by qmake.
+#     * $(QT_LDFLAGS): Same thing as $(QT_LFLAGS).
+#     * $(QT_LIBS): LIBS defined by qmake.
+#
+# You *MUST* invoke $(MOC) and/or $(UIC) where necessary. AutoTroll provides
+# you with Makerules to ease this, here is a sample Makefile.am to use with
+# AutoTroll which builds the code given in the chapter 7 of the Qt Tutorial:
+# http://doc.trolltech.com/4.2/tutorial-t7.html
+#
+# -------------------------------------------------------------------------
+# include $(top_srcdir)/build-aux/autotroll.mk
+#
+# ACLOCAL_AMFLAGS = -I build-aux
+#
+# bin_PROGRAMS = lcdrange
+# lcdrange_SOURCES =  $(BUILT_SOURCES) lcdrange.cpp lcdrange.h main.cpp
+# lcdrange_CXXFLAGS = $(QT_CXXFLAGS) $(AM_CXXFLAGS)
+# lcdrange_CPPFLAGS = $(QT_CPPFLAGS) $(AM_CPPFLAGS)
+# lcdrange_LDFLAGS  = $(QT_LDFLAGS) $(LDFLAGS)
+# lcdrange_LDADD    = $(QT_LIBS) $(LDADD)
+#
+# BUILT_SOURCES = lcdrange.moc.cpp
+# -------------------------------------------------------------------------
+#
+# Note that your MOC, UIC and QRC files *MUST* be listed manually in
+# BUILT_SOURCES. If you name them properly (eg: .moc.cc, .qrc.cc, .ui.cc -- of
+# course you can use .cpp or .cxx or .C rather than .cc) AutoTroll will build
+# them automagically for you (using implicit rules defined in autotroll.mk).
+
+m4_define([_AUTOTROLL_SERIAL], [m4_translit([
+# serial 5
+], [#
+], [])])
+
+
+m4_ifdef([AX_INSTEAD_IF], [],
+[AC_DEFUN([AX_INSTEAD_IF],
+  [m4_ifval([$1],
+    [AC_MSG_WARN([$2]); [$1]],
+    [AC_MSG_ERROR([$2])])])])
+
+m4_pattern_forbid([^AT_])dnl
+m4_pattern_forbid([^_AT_])dnl
+
+# AT_WITH_QT([QT_modules], [QT_config], [QT_misc], [RUN-IF-FAILED], [RUN-IF-OK])
+# ------------------------------------------------------------------------------
+# Enable Qt support and add an option --with-qt to the configure script.
+#
+# The QT_modules argument is optional and defines extra modules to enable or
+# disable (it's equivalent to the QT variable in .pro files). Modules can be
+# specified as follows:
+#
+# AT_WITH_QT   => No argument -> No QT value.
+#                                Qmake sets it to "core gui" by default.
+# AT_WITH_QT([xml])   => QT += xml
+# AT_WITH_QT([+xml])  => QT += xml
+# AT_WITH_QT([-gui])  => QT -= gui
+# AT_WITH_QT([xml -gui +sql svg])  => QT += xml sql svg
+#                                     QT -= gui
+#
+# The QT_config argument is also optional and follows the same convention as
+# QT_modules. Instead of changing the QT variable, it changes the CONFIG
+# variable, which is used to tweak configuration and compiler options.
+#
+# The last argument, QT_misc (also optional) will be copied as-is the .pro
+# file used to guess how to compile Qt apps. You may use it to further tweak
+# the build process of Qt apps if tweaking the QT or CONFIG variables isn't
+# enough for you.
+#
+# RUN-IF-FAILED is arbitrary code to execute if Qt cannot be found or if any
+# problem happens.  If this argument is omitted, then AC_MSG_ERROR will be
+# called.  RUN-IF-OK is arbitrary code to execute if Qt was successfully found.
+AC_DEFUN([AT_WITH_QT],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CXX])dnl
+echo "$as_me: this is autotroll.m4[]_AUTOTROLL_SERIAL" >&AS_MESSAGE_LOG_FD
+
+  test x"$TROLL" != x && echo 'ViM rox emacs.'
+
+dnl Memo: AC_ARG_WITH(package, help-string, [if-given], [if-not-given])
+  AC_ARG_WITH([qt],
+              [AS_HELP_STRING([--with-qt],
+                 [Path to Qt @<:@Look in PATH and /usr/local/Trolltech@:>@])],
+              [QT_PATH=$withval])
+
+  # this is a hack to get decent flow control with 'break'
+  for _qt_ignored in once; do
+
+  # Find Qt.
+  AC_ARG_VAR([QT_PATH], [Path to the Qt installation])
+  if test -d /usr/local/Trolltech; then
+    # Try to find the latest version.
+    tmp_qt_paths=`echo /usr/local/Trolltech/*/bin | tr ' ' '\n' | sort -nr \
+                                              | xargs | sed 's/  */:/g'`
+  fi
+  # Path to which recent MacPorts (~v1.7) install Qt4.
+  test -d /opt/local/libexec/qt4-mac/bin \
+    && tmp_qt_paths="$tmp_qt_paths:/opt/local/libexec/qt4-mac/bin"
+
+  # Find qmake.
+  AC_ARG_VAR([QMAKE], [Qt Makefile generator command])
+  AC_PATH_PROGS([QMAKE], [qmake qmake-qt4 qmake-qt3], [missing],
+                [$QT_DIR:$QT_PATH:$PATH:$tmp_qt_paths])
+  if test x"$QMAKE" = xmissing; then
+    AX_INSTEAD_IF([$4], [Cannot find qmake in your PATH. Try using --with-qt.])
+    break
+  fi
+
+  # Find moc (Meta Object Compiler).
+  AC_ARG_VAR([MOC], [Qt Meta Object Compiler command])
+  AC_PATH_PROGS([MOC], [moc moc-qt4 moc-qt3], [missing],
+                [$QT_PATH:$PATH:$tmp_qt_paths])
+  if test x"$MOC" = xmissing; then
+    AX_INSTEAD_IF([$4],
+   [Cannot find moc (Meta Object Compiler) in your PATH. Try using --with-qt.])
+    break
+  fi
+
+  # Find uic (User Interface Compiler).
+  AC_ARG_VAR([UIC], [Qt User Interface Compiler command])
+  AC_PATH_PROGS([UIC], [uic uic-qt4 uic-qt3 uic3], [missing],
+                [$QT_PATH:$PATH:$tmp_qt_paths])
+  if test x"$UIC" = xmissing; then
+    AX_INSTEAD_IF([$4],
+[Cannot find uic (User Interface Compiler) in your PATH. Try using --with-qt.])
+    break
+  fi
+
+  # Find rcc (Qt Resource Compiler).
+  AC_ARG_VAR([RCC], [Qt Resource Compiler command])
+  AC_PATH_PROGS([RCC], [rcc], [false], [$QT_PATH:$PATH:$tmp_qt_paths])
+  if test x"$UIC" = xfalse; then
+    AC_MSG_WARN([Cannot find rcc (Qt Resource Compiler) in your PATH.\
+  Try using --with-qt.])
+  fi
+
+  AC_MSG_CHECKING([whether host operating system is Darwin])
+  at_darwin=no
+  at_qmake_args=
+  case $host_os in
+    darwin*)
+      at_darwin=yes
+      at_qmake_args='-spec macx-g++'
+      ;;
+  esac
+  AC_MSG_RESULT([$at_darwin])
+
+  # If we don't know the path to Qt, guess it from the path to qmake.
+  if test x"$QT_PATH" = x; then
+    QT_PATH=`dirname "$QMAKE"`
+  fi
+  if test x"$QT_PATH" = x; then
+    AX_INSTEAD_IF([$4],
+                  [Cannot find the path to your Qt install. Use --with-qt.])
+    break
+  fi
+  AC_SUBST([QT_PATH])
+
+  # Get ready to build a test-app with Qt.
+  if mkdir conftest.dir && cd conftest.dir; then :; else
+    AX_INSTEAD_IF([$4], [Cannot mkdir conftest.dir or cd to that directory.])
+    break
+  fi
+
+  cat >conftest.h <<_ASEOF
+#include <QObject>
+
+class Foo: public QObject
+{
+  Q_OBJECT;
+public:
+  Foo();
+  ~Foo() {}
+public Q_SLOTS:
+  void setValue(int value);
+Q_SIGNALS:
+  void valueChanged(int newValue);
+private:
+  int value_;
+};
+_ASEOF
+
+  cat >conftest.cpp <<_ASEOF
+#include "conftest.h"
+Foo::Foo()
+  : value_ (42)
+{
+  connect(this, SIGNAL(valueChanged(int)), this, SLOT(setValue(int)));
+}
+
+void Foo::setValue(int value)
+{
+  value_ = value;
+}
+
+int main()
+{
+  Foo f;
+}
+_ASEOF
+  if $QMAKE -project; then :; else
+    AX_INSTEAD_IF([$4], [Calling $QMAKE -project failed.])
+    break
+  fi
+
+  # Find the .pro file generated by qmake.
+  pro_file='conftest.dir.pro'
+  test -f $pro_file || pro_file=`echo *.pro`
+  if test -f "$pro_file"; then :; else
+    AX_INSTEAD_IF([$4], [Can't find the .pro file generated by Qmake.])
+    break
+  fi
+
+dnl Tweak the value of QT in the .pro if have been the 1st arg.
+m4_ifval([$1], [_AT_TWEAK_PRO_FILE([QT], [$1])])
+
+dnl Tweak the value of CONFIG in the .pro if have been given a 2nd arg.
+m4_ifval([$2], [_AT_TWEAK_PRO_FILE([CONFIG], [$2])])
+
+m4_ifval([$3],
+[ # Add the extra-settings the user wants to set in the .pro
+  echo "$3" >>"$pro_file"
+])
+
+  echo "$as_me:$LINENO: Invoking $QMAKE on $pro_file" >&AS_MESSAGE_LOG_FD
+  sed 's/^/| /' "$pro_file" >&AS_MESSAGE_LOG_FD
+
+  if $QMAKE $at_qmake_args; then :; else
+    AX_INSTEAD_IF([$4], [Calling $QMAKE $at_qmake_args failed.])
+    break
+  fi
+
+  # QMake has a very annoying misfeature: sometimes it generates Makefiles
+  # where all the references to the files from the Qt installation are
+  # relative.  We can't use them as-is because if we take, say, a
+  # -I../../usr/include/Qt from that Makefile, the flag is invalid as soon
+  # as we use it in another (sub) directory.  So what this perl pass does is
+  # that it rewrite all relative paths to absolute paths.  Another problem
+  # when building on Cygwin is that QMake mixes paths with blackslashes and
+  # forward slashes and paths must be handled with extra care because of the
+  # stupid Windows drive letters.
+  echo "$as_me:$LINENO: fixing the Makefiles:" Makefile* >&AS_MESSAGE_LOG_FD
+  cat >fixmk.pl <<\EOF
+[use strict;
+use Cwd qw(cwd abs_path);
+# This variable is useful on Cygwin for the following reason: Say that you are
+# in `/' (that is, in fact you are in C:/cygwin, or something like that) if you
+# `cd ..' then obviously you remain in `/' (that is in C:/cygwin).  QMake
+# generates paths that are relative to C:/ (or another driver letter, whatever)
+# so the trick to get the `..' resolved properly is to prepend the absolute
+# path of the current working directory in a Windows-style.  C:/cygwin/../ will
+# properly become C:/.
+my $d = "";
+my $r2a = 0;
+my $b2f = 0;
+
+my $cygwin = 0;
+if ($^O eq "cygwin") {
+  $cygwin = 1;
+  $d = cwd();
+  $d = `cygpath --mixed '$d'`;
+  chomp($d);
+  $d .= "/";
+}
+
+sub rel2abs($)
+{
+  my $p = $d . shift;
+  # print "r2a p=$p";
+  -e $p || return $p;
+  if ($cygwin) {
+    $p = `cygpath --mixed '$p'`;
+    chomp($p);
+  }
+  else {
+    # Do not use abs_path on Cygwin: it incorrectly resolves the paths that are
+    # relative to C:/ rather than `/'.
+    $p = abs_path($p);
+  }
+  # print " -> $p\n";
+  ++$r2a;
+  return $p;
+}
+
+# Only useful on Cygwin.
+sub back2forward($)
+{
+  my $p = shift;
+  # print "b2f p=$p";
+  -e $p || return $p;
+  $p = `cygpath --mixed '$p'`;
+  chomp($p);
+  # print " -> $p\n";
+  ++$b2f;
+  return $p;
+}
+
+foreach my $mk (@ARGV)
+{
+  next if $mk =~ /~$/;
+  open(MK, $mk) or die("open $mk: $!");
+  # print "mk=$mk\n";
+  my $file = join("", <MK>);
+  close(MK) or die("close $mk: $!");
+  rename $mk, $mk . "~" or die("rename $mk: $!");
+  $file =~ s{(?:\.\.[\\/])+(?:[^"'\s:]+)}{rel2abs($&)}gse;
+  $file =~ s{(?:[a-zA-Z]:[\\/])?(?:[^"\s]+\\[^"\s:]+)+}
+            {back2forward($&)}gse if $cygwin;
+  open(MK, ">", $mk) or die("open >$mk: $!");
+  print MK $file;
+  close(MK) or die("close >$mk: $!");
+  print "$mk: updated $r2a relative paths and $b2f backslash-style paths\n";
+  $r2a = 0;
+  $b2f = 0;
+}]
+EOF
+
+  perl >&AS_MESSAGE_LOG_FD -w fixmk.pl Makefile* ||
+  AC_MSG_WARN([failed to fix the Makefiles generated by $QMAKE])
+  rm -f fixmk.pl
+
+  # Try to compile a simple Qt app.
+  AC_CACHE_CHECK([whether we can build a simple Qt app], [at_cv_qt_build],
+  [at_cv_qt_build=ko
+  : ${MAKE=make}
+
+  if $MAKE >&AS_MESSAGE_LOG_FD 2>&1; then
+    at_cv_qt_build='ok, looks like Qt 4'
+  else
+    echo "$as_me:$LINENO: Build failed, trying to #include <qobject.h> \
+instead" >&AS_MESSAGE_LOG_FD
+    sed 's/<QObject>/<qobject.h>/' conftest.h > tmp.h && mv tmp.h conftest.h
+    if $MAKE >&AS_MESSAGE_LOG_FD 2>&1; then
+      at_cv_qt_build='ok, looks like Qt 3'
+    else
+      # Sometimes (such as on Debian) build will fail because Qt hasn't been
+      # installed in debug mode and qmake tries (by default) to build apps in
+      # debug mode => Try again in release mode.
+      echo "$as_me:$LINENO: Build failed, trying to enforce release mode" \
+            >&AS_MESSAGE_LOG_FD
+
+      _AT_TWEAK_PRO_FILE([CONFIG], [+release])
+
+      sed 's/<qobject.h>/<QObject>/' conftest.h > tmp.h && mv tmp.h conftest.h
+      if $MAKE >&AS_MESSAGE_LOG_FD 2>&1; then
+        at_cv_qt_build='ok, looks like Qt 4, release mode forced'
+      else
+        echo "$as_me:$LINENO: Build failed, trying to #include <qobject.h> \
+instead" >&AS_MESSAGE_LOG_FD
+        sed 's/<QObject>/<qobject.h>/' conftest.h >tmp.h && mv tmp.h conftest.h
+        if $MAKE >&AS_MESSAGE_LOG_FD 2>&1; then
+          at_cv_qt_build='ok, looks like Qt 3, release mode forced'
+        else
+          at_cv_qt_build=ko
+          echo "$as_me:$LINENO: failed program was:" >&AS_MESSAGE_LOG_FD
+          sed 's/^/| /' conftest.h >&AS_MESSAGE_LOG_FD
+          echo "$as_me:$LINENO: failed program was:" >&AS_MESSAGE_LOG_FD
+          sed 's/^/| /' conftest.cpp >&AS_MESSAGE_LOG_FD
+        fi # if make with Qt3-style #include and release mode forced.
+      fi # if make with Qt4-style #include and release mode forced.
+    fi # if make with Qt3-style #include.
+  fi # if make with Qt4-style #include.
+  ])dnl end: AC_CACHE_CHECK(at_cv_qt_build)
+
+  if test x"$at_cv_qt_build" = xko; then
+    AX_INSTEAD_IF([$4], [Cannot build a test Qt program])
+    cd ..
+    break
+  fi
+  QT_VERSION_MAJOR=`echo "$at_cv_qt_build" | sed 's/[[^0-9]]*//g'`
+  AC_SUBST([QT_VERSION_MAJOR])
+
+  # This sed filter is applied after an expression of the form: /^FOO.*=/!d;
+  # It starts by removing the beginning of the line, removing references to
+  # SUBLIBS, removing unnecessary whitespaces at the beginning, and prefixes
+  # all variable uses by QT_.
+  qt_sed_filter='s///;
+                 s/$(SUBLIBS)//g;
+                 s/^ *//;
+                 s/\$(\(@<:@A-Z_@:>@@<:@A-Z_@:>@*\))/$(QT_\1)/g'
+
+  # Find the Makefile (qmake happens to generate a fake Makefile which invokes
+  # a Makefile.Debug or Makefile.Release). We we have both, we'll pick the
+  # Makefile.Release. The reason is that the main difference is that release
+  # uses -Os and debug -g. We can override -Os by passing another -O but we
+  # usually don't override -g.
+  if test -f Makefile.Release; then
+    at_mfile='Makefile.Release'
+  else
+    at_mfile='Makefile'
+  fi
+  if test -f $at_mfile; then :; else
+    AX_INSTEAD_IF([$4], [Cannot find the Makefile generated by qmake.])
+    cd ..
+    break
+  fi
+
+  # Find the DEFINES of Qt (should have been named CPPFLAGS).
+  AC_CACHE_CHECK([for the DEFINES to use with Qt], [at_cv_env_QT_DEFINES],
+  [at_cv_env_QT_DEFINES=`sed "/^DEFINES@<:@^A-Z=@:>@*=/!d;$qt_sed_filter" $at_mfile`])
+  AC_SUBST([QT_DEFINES], [$at_cv_env_QT_DEFINES])
+
+  # Find the CFLAGS of Qt (We can use Qt in C?!)
+  AC_CACHE_CHECK([for the CFLAGS to use with Qt], [at_cv_env_QT_CFLAGS],
+  [at_cv_env_QT_CFLAGS=`sed "/^CFLAGS@<:@^A-Z=@:>@*=/!d;$qt_sed_filter" $at_mfile`])
+  AC_SUBST([QT_CFLAGS], [$at_cv_env_QT_CFLAGS])
+
+  # Find the CXXFLAGS of Qt.
+  AC_CACHE_CHECK([for the CXXFLAGS to use with Qt], [at_cv_env_QT_CXXFLAGS],
+  [at_cv_env_QT_CXXFLAGS=`sed "/^CXXFLAGS@<:@^A-Z=@:>@*=/!d;$qt_sed_filter" $at_mfile`])
+  AC_SUBST([QT_CXXFLAGS], [$at_cv_env_QT_CXXFLAGS])
+
+  # Find the INCPATH of Qt.
+  AC_CACHE_CHECK([for the INCPATH to use with Qt], [at_cv_env_QT_INCPATH],
+  [at_cv_env_QT_INCPATH=`sed "/^INCPATH@<:@^A-Z=@:>@*=/!d;$qt_sed_filter" $at_mfile`])
+  AC_SUBST([QT_INCPATH], [$at_cv_env_QT_INCPATH])
+
+  AC_SUBST([QT_CPPFLAGS], ["$at_cv_env_QT_DEFINES $at_cv_env_QT_INCPATH"])
+
+  # Find the LFLAGS of Qt (Should have been named LDFLAGS)
+  AC_CACHE_CHECK([for the LDFLAGS to use with Qt], [at_cv_env_QT_LDFLAGS],
+  [at_cv_env_QT_LDFLAGS=`sed "/^LFLAGS@<:@^A-Z=@:>@*=/!d;$qt_sed_filter" $at_mfile`])
+  AC_SUBST([QT_LFLAGS], [$at_cv_env_QT_LDFLAGS])
+  AC_SUBST([QT_LDFLAGS], [$at_cv_env_QT_LDFLAGS])
+
+  # Find the LIBS of Qt.
+  AC_CACHE_CHECK([for the LIBS to use with Qt], [at_cv_env_QT_LIBS],
+  [at_cv_env_QT_LIBS=`sed "/^LIBS@<:@^A-Z@:>@*=/!d;$qt_sed_filter" $at_mfile`
+   if test x$at_darwin = xyes; then
+     # Fix QT_LIBS: as of today Libtool (GNU Libtool 1.5.23a) doesn't handle
+     # -F properly. The "bug" has been fixed on 22 October 2006
+     # by Peter O'Gorman but we provide backward compatibility here.
+     at_cv_env_QT_LIBS=`echo "$at_cv_env_QT_LIBS" \
+                             | sed 's/^-F/-Wl,-F/;s/ -F/ -Wl,-F/g'`
+   fi
+  ])
+  AC_SUBST([QT_LIBS], [$at_cv_env_QT_LIBS])
+
+  cd .. && rm -rf conftest.dir
+
+  # Run the user code
+  $5
+
+  done  # end hack (useless for to be able to use break)
+])
+
+# AT_REQUIRE_QT_VERSION(QT_version, RUN-IF-FAILED, RUN-IF-OK)
+# -----------------------------------------------------------
+# Check (using qmake) that Qt's version "matches" QT_version.
+# Must be run AFTER AT_WITH_QT. Requires autoconf 2.60.
+#
+# RUN-IF-FAILED is arbitrary code to execute if Qt cannot be found or if any
+# problem happens.  If this argument is omitted, then AC_MSG_ERROR will be
+# called.  RUN-IF-OK is arbitrary code to execute if Qt was successfully found.
+AC_DEFUN([AT_REQUIRE_QT_VERSION],
+[ AC_PREREQ([2.60])
+  # this is a hack to get decent flow control with 'break'
+  for _qt_ignored in once; do
+
+  if test x"$QMAKE" = x; then
+    AX_INSTEAD_IF([$2],
+                  [\$QMAKE is empty.\
+  Did you invoke AT@&t@_WITH_QT before AT@&t@_REQUIRE_QT_VERSION?])
+    break
+  fi
+  AC_CACHE_CHECK([for Qt's version], [at_cv_QT_VERSION],
+  [echo "$as_me:$LINENO: Running $QMAKE --version:" >&AS_MESSAGE_LOG_FD
+  $QMAKE --version >&AS_MESSAGE_LOG_FD 2>&1
+  qmake_version_sed=['/^.*\([0-9]\.[0-9]\.[0-9]\).*$/!d;s//\1/']
+  at_cv_QT_VERSION=`$QMAKE --version 2>&1 | sed "$qmake_version_sed"`])
+  if test x"$at_cv_QT_VERSION" = x; then
+    AX_INSTEAD_IF([$2], [Cannot detect Qt's version.])
+    break
+  fi
+  AC_SUBST([QT_VERSION], [$at_cv_QT_VERSION])
+  AS_VERSION_COMPARE([$QT_VERSION], [$1],
+    [AX_INSTEAD_IF([$2; break;], [This package requires Qt $1 or above.])])
+
+  # Run the user code
+  $3
+
+  done  # end hack (useless for to be able to use break)
+])
+
+# _AT_TWEAK_PRO_FILE(QT_VAR, VALUE)
+# ---------------------------
+# @internal. Tweak the variable QT_VAR in the .pro.
+# VALUE is an IFS-separated list of value and each value is rewritten
+# as follows:
+#   +value  => QT_VAR += value
+#   -value  => QT_VAR -= value
+#    value  => QT_VAR += value
+AC_DEFUN([_AT_TWEAK_PRO_FILE],
+[ # Tweak the value of $1 in the .pro file for $2.
+
+  qt_conf=''
+  for at_mod in $2; do
+    at_mod=`echo "$at_mod" | sed 's/^-//; tough
+                                  s/^+//; beef
+                                  :ough
+                                  s/^/$1 -= /;n
+                                  :eef
+                                  s/^/$1 += /'`
+    qt_conf="$qt_conf
+$at_mod"
+  done
+  echo "$qt_conf" | sed 1d >>"$pro_file"
+])
diff --git a/autotroll.mk b/autotroll.mk
new file mode 100644
index 0000000000000000000000000000000000000000..45d6cf36c66a27f93dff6fec08b32cafe68e8a74
--- /dev/null
+++ b/autotroll.mk
@@ -0,0 +1,108 @@
+# Makerules.
+# This file is part of AutoTroll.
+# Copyright (C) 2006, 2007, 2009, 2010  Benoit Sigoure.
+#
+# AutoTroll is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+#
+# In addition, as a special exception, the copyright holders of AutoTroll
+# give you unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the macros of
+# AutoTroll.  You need not follow the terms of the GNU General Public License
+# when using or distributing such scripts, even though portions of the text of
+# AutoTroll appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes AutoTroll.
+#
+# This special exception to the GPL applies to versions of AutoTroll
+# released by the copyright holders of AutoTroll.  Note that people who make
+# modified versions of AutoTroll are not obligated to grant this special
+# exception for their modified versions; it is their choice whether to do so.
+# The GNU General Public License gives permission to release a modified version
+# without this exception; this exception also makes it possible to release a
+# modified version which carries forward this exception.
+
+ # ------------- #
+ # DOCUMENTATION #
+ # ------------- #
+
+# See autotroll.m4 :)
+
+
+SUFFIXES = .moc.cpp .moc.cc .moc.cxx .moc.C .h .hh .hpp \
+           .ui .ui.h .ui.hh .ui.hpp \
+           .qrc .qrc.cpp .qrc.cc .qrc.cxx .qrc.C
+
+# --- #
+# MOC #
+# --- #
+
+.hpp.moc.cpp:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+.hh.moc.cpp:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+.h.moc.cpp:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+
+.hpp.moc.cc:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+.hh.moc.cc:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+.h.moc.cc:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+
+.hpp.moc.cxx:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+.hh.moc.cxx:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+.h.moc.cxx:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+
+.hpp.moc.C:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+.hh.moc.C:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+.h.moc.C:
+	$(MOC) $(QT_CPPFLAGS) $(EXTRA_CPPFLAGS) $< -o $@
+
+# --- #
+# UIC #
+# --- #
+
+.ui.ui.hpp:
+	$(UIC) $< -o $@
+
+.ui.ui.hh:
+	$(UIC) $< -o $@
+
+.ui.ui.h:
+	$(UIC) $< -o $@
+
+# --- #
+# RCC #
+# --- #
+
+.qrc.qrc.cpp:
+	$(RCC) -name `echo "$<" | sed 's|^.*/\(.*\)\.qrc$$|\1|'` $< -o $@
+
+.qrc.qrc.cc:
+	$(RCC) -name `echo "$<" | sed 's|^.*/\(.*\)\.qrc$$|\1|'` $< -o $@
+
+.qrc.qrc.cxx:
+	$(RCC) -name `echo "$<" | sed 's|^.*/\(.*\)\.qrc$$|\1|'` $< -o $@
+
+.qrc.qrc.C:
+	$(RCC) -name `echo "$<" | sed 's|^.*/\(.*\)\.qrc$$|\1|'` $< -o $@
+
+DISTCLEANFILES = $(BUILT_SOURCES)
diff --git a/configure.in b/configure.in
index 225fdd01e561b4d692a1d80b894b174712314736..a6525da051cf384a04753d0a4e23c4058bb1c7ec 100644
--- a/configure.in
+++ b/configure.in
@@ -4,6 +4,7 @@ AC_INIT(JSBSim.cpp, 1.0.rc3-advtrim-7, jon@jsbsim.org)
 dnl set the $host variable based on local machine/os
 AC_CANONICAL_TARGET
 
+AC_CONFIG_AUX_DIR([m4])
 AM_INIT_AUTOMAKE(jsbsim, 1.0.rc3-advtrim-7)
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -105,6 +106,9 @@ AC_DEFINE(socklen_t,size_t)], [
 AC_MSG_RESULT(int)
 AC_DEFINE(socklen_t,int)])])
 
+# AutoTroll with Qt
+AT_WITH_QT([gui opengl])
+
 AC_OUTPUT( 
 	jsbsim.pc 
 		Makefile 
@@ -143,6 +147,7 @@ AC_OUTPUT(
 	src/simgear/props/Makefile 
 	src/simgear/magvar/Makefile 
 	src/simgear/misc/Makefile 
+	gui/Makefile
 	engine/Makefile 
 	data_output/Makefile 
 	scripts/Makefile 
diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..eb43d9d8b1ab67794c6b599c7621bad456b89394
--- /dev/null
+++ b/gui/MainWindow.cpp
@@ -0,0 +1,467 @@
+/*
+ * MainWindow.cpp
+ * Copyright (C) James Goppert 2010 <james.goppert@gmail.com>
+ *
+ * MainWindow.cpp is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MainWindow.cpp is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "MainWindow.hpp"
+#include <QFileDialog>
+#include <QMessageBox>
+#include <osg/Vec3d>
+
+#include <cstdlib>
+#include <fstream>
+#include <models/FGAircraft.h>
+#include <models/propulsion/FGEngine.h>
+#include <models/propulsion/FGTurbine.h>
+#include <models/propulsion/FGTurboProp.h>
+
+MainWindow::MainWindow() : sceneRoot(new osg::Group),
+	callback(new SolverCallback(this)), trimThread(this), simThread(this),
+	ss(NULL), trimmer(NULL), fdm(NULL)
+{
+    setupUi(this);
+    viewer->setSceneData(sceneRoot);
+    viewer->setCameraManipulator(new osgGA::TrackballManipulator);
+    viewer->getCameraManipulator()->setHomePosition(osg::Vec3d(30,30,-30),osg::Vec3d(0,0,0),osg::Vec3d(0,0,-1),false);
+    viewer->getCameraManipulator()->home(0);
+    sceneRoot->addChild(new mavsim::visualization::Frame(20,"N","E","D"));
+
+	// read initial settings
+	QCoreApplication::setOrganizationName("openmav");
+    QCoreApplication::setOrganizationDomain("github.com/mavsim");
+    QCoreApplication::setApplicationName("mavsim");
+
+	settings = new QSettings;
+	readSettings();
+	writeSettings();
+
+	// load plane
+    try
+    {
+        plane = new mavsim::visualization::Plane;
+        plane->addChild(new mavsim::visualization::Frame(15,"X","Y","Z"));
+        sceneRoot->addChild(plane);
+    }
+    catch(const std::exception & e)
+    {
+		showMsg(e.what());		
+    }
+
+	// connect signals and slots
+	connect(this,SIGNAL(showMsgBuffered(const QString &)),
+			this,SLOT(showMsg(const QString &)),Qt::QueuedConnection);
+}
+
+MainWindow::~MainWindow()
+{
+	writeSettings();
+    delete viewer;
+}
+
+void MainWindow::writeSettings()
+{
+	settings->beginGroup("mainwindow");
+	settings->setValue("enginePath",lineEdit_enginePath->text());
+	settings->setValue("systemsPath",lineEdit_systemsPath->text());
+	settings->setValue("aircraftPath",lineEdit_aircraftPath->text());
+	settings->setValue("aircraft",lineEdit_aircraft->text());
+	settings->setValue("initScript",lineEdit_initScript->text());
+	settings->endGroup();
+}
+
+void MainWindow::readSettings()
+{
+	QString root(DATADIR);
+	settings->beginGroup("mainwindow");
+	lineEdit_enginePath->setText(settings->value("enginePath",root+"/easystar/Engine").toString());
+	lineEdit_systemsPath->setText(settings->value("systemsPath",root+"/easystar/Systems").toString());
+	lineEdit_aircraftPath->setText(settings->value("aircraftPath",root+"/easystar").toString());
+	lineEdit_aircraft->setText(settings->value("aircraft","easystar-windtunnel").toString());
+	lineEdit_initScript->setText(settings->value("initScript","").toString());
+	settings->endGroup();
+}
+
+void MainWindow::on_toolButton_enginePath_pressed()
+{
+    lineEdit_enginePath->setText(QFileDialog::getExistingDirectory(
+                                     this, tr("Select Engine Path"),
+                                     lineEdit_enginePath->text(),
+                                     QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks));
+}
+
+void MainWindow::on_toolButton_systemsPath_pressed()
+{
+    lineEdit_systemsPath->setText(QFileDialog::getExistingDirectory(
+                                      this, tr("Select Systems Path"),
+                                      lineEdit_systemsPath->text(),
+                                      QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks));
+}
+
+void MainWindow::on_toolButton_aircraftPath_pressed()
+{
+    lineEdit_aircraftPath->setText(QFileDialog::getExistingDirectory(
+                                       this, tr("Select Aircraft Path"),
+                                       lineEdit_aircraftPath->text(),
+                                       QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks));
+}
+
+void MainWindow::on_toolButton_aircraft_pressed()
+{
+    QString path(QFileDialog::getExistingDirectory(
+                     this, tr("Select Aircraft Directory"),
+                     lineEdit_aircraftPath->text(),
+                     QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks));
+    if (!path.isNull())
+    {
+        QFileInfo pathInfo(path);
+        lineEdit_aircraft->setText(pathInfo.fileName());
+    }
+}
+
+void MainWindow::on_toolButton_initScript_pressed()
+{
+    lineEdit_initScript->setText(QFileDialog::getOpenFileName(this,
+                                 tr("Select Initialization Script"),lineEdit_initScript->text(),
+                                 tr("JSBSim Scripts (*.xml)")));
+}
+
+void MainWindow::on_pushButton_trim_pressed()
+{
+	on_pushButton_stop_pressed();
+	writeSettings();
+	try
+	{
+		trimThread.start();
+	}
+	catch(const std::exception & e)
+	{
+		QMessageBox msgBox;
+		msgBox.setText(e.what());
+		msgBox.exec();
+	}
+	catch(...)
+	{
+		QMessageBox msgBox;
+		msgBox.setText("unknown trim exception");
+		msgBox.exec();
+	}
+}
+
+void MainWindow::on_pushButton_linearize_pressed()
+{
+	QMutexLocker locker(&fdmMutex);
+
+	on_pushButton_stop_pressed();
+	writeSettings();
+	using namespace JSBSim;
+
+	if (!ss)
+	{
+		showMsg("trim the aircraft first");
+		return;
+	}
+
+	std::cout << "\nlinearization: " << std::endl;
+
+
+	std::vector< std::vector<double> > A,B,C,D;
+	std::vector<double> x0 = ss->x.get(), u0 = ss->u.get();
+	std::vector<double> y0 = x0; // state feedback
+	std::cout << ss << std::endl;
+
+	ss->linearize(x0,u0,y0,A,B,C,D);
+	for (int i = 0; i<A.size(); i++)
+	{
+		for (int j = 0; j<A[0].size(); j++)
+		{
+			std::cout << A[i][j];
+		}
+		std::cout << "\n";
+	}
+	int width=10;
+	std::cout.precision(3);
+	std::cout
+	<< std::fixed
+	<< std::right
+	<< "\nA=\n" << std::setw(width) << A
+	<< "\nB=\n" << std::setw(width) << B
+	<< "\nC=\n" << std::setw(width) << C
+	<< "\nD=\n" << std::setw(width) << D
+	<< std::endl;
+
+	// write scicoslab file
+	std::string aircraft = lineEdit_aircraft->text().toStdString();
+	std::ofstream scicos(std::string(aircraft+"_lin.sce").c_str());
+	scicos.precision(10);
+	width=20;
+	scicos
+	<< std::scientific
+	<< "x0=..\n" << std::setw(width) << x0 << ";\n"
+	<< "u0=..\n" << std::setw(width) << u0 << ";\n"
+	<< "sys = syslin('c',..\n"
+	<< std::setw(width) << A << ",..\n"
+	<< std::setw(width) << B << ",..\n"
+	<< std::setw(width) << C << ",..\n"
+	<< std::setw(width) << D << ");\n"
+	<< "tfm = ss2tf(sys);\n"
+	<< std::endl;
+}
+
+void MainWindow::on_pushButton_stop_pressed()
+{
+	stopSolver();
+	simThread.quit();
+	trimThread.quit();
+}
+
+void MainWindow::on_pushButton_simulate_pressed()
+{
+	on_pushButton_stop_pressed();
+	simThread.start();
+}
+
+void MainWindow::stopSolver()
+{
+	stopRequested = true;
+}
+
+void MainWindow::showMsg(const QString & str)
+{
+	QMessageBox msgBox;
+	msgBox.setText(str);
+	msgBox.exec();
+};
+
+void MainWindow::trim()
+{
+	QMutexLocker locker(&fdmMutex);
+	using namespace JSBSim;
+
+	// flight conditions
+	if (ss)
+	{
+		delete ss;
+		ss = NULL;
+	}
+	if (fdm)
+	{
+		delete fdm;
+		fdm = NULL;
+	}
+	if (trimmer)
+	{
+		delete trimmer;
+		trimmer = NULL;
+	}
+	if (!fdm)
+	fdm = new FGFDMExec;
+	double dt = 1./atof(lineEdit_modelSimRate->text().toAscii());
+	FGTrimmer::Constraints constraints;
+	constraints.velocity = atof(lineEdit_velocity->text().toAscii());
+	constraints.altitude= atof(lineEdit_altitude->text().toAscii());
+	constraints.gamma= atof(lineEdit_gamma->text().toAscii())*M_PI/180.0;
+	constraints.rollRate= atof(lineEdit_rollRate->text().toAscii());
+	constraints.pitchRate= atof(lineEdit_pitchRate->text().toAscii());
+	constraints.yawRate= atof(lineEdit_yawRate->text().toAscii());
+	bool stabAxisRoll = checkBox_stabAxisRoll->isChecked();
+	bool variablePropPitch = checkBox_variablePropPitch->isChecked();
+
+	// paths
+	std::string aircraft=lineEdit_aircraft->text().toStdString();
+	std::string aircraftPath=lineEdit_aircraftPath->text().toStdString();
+	std::string enginePath=lineEdit_enginePath->text().toStdString();
+	std::string systemsPath=lineEdit_systemsPath->text().toStdString();
+   
+	// solver properties 
+	bool showConvergeStatus = checkBox_showConvergence->isChecked();
+	bool showSimplex = checkBox_showSimplex->isChecked();
+	bool pause = checkBox_pause->isChecked();
+	int debugLevel = atoi(comboBox_debugLevel->currentText().toAscii());
+	double rtol = atof(lineEdit_rtol->text().toAscii());
+	double abstol = atof(lineEdit_abstol->text().toAscii());
+	double speed = atof(lineEdit_speed->text().toAscii());
+	double random = atof(lineEdit_random->text().toAscii());
+	int iterMax = atof(lineEdit_iterMax->text().toAscii());
+
+	// initial solver state
+	int n = 6;
+	std::vector<double> initialGuess(n), lowerBound(n), upperBound(n), initialStepSize(n);
+
+	lowerBound[0] = atof(lineEdit_throttleMin->text().toAscii())/100.0;
+	lowerBound[1] = atof(lineEdit_elevatorMin->text().toAscii())/100.0;
+	lowerBound[2] = atof(lineEdit_alphaMin->text().toAscii())*M_PI/180.0;
+	lowerBound[3] = atof(lineEdit_aileronMin->text().toAscii())/100.0;
+	lowerBound[4] = atof(lineEdit_rudderMin->text().toAscii())/100.0;
+	lowerBound[5] = atof(lineEdit_betaMin->text().toAscii())*M_PI/180.0;
+
+	upperBound[0] = atof(lineEdit_throttleMax->text().toAscii())/100.0; 
+	upperBound[1] = atof(lineEdit_elevatorMax->text().toAscii())/100.0; 
+	upperBound[2] = atof(lineEdit_alphaMax->text().toAscii())*M_PI/180.0; 
+	upperBound[3] = atof(lineEdit_aileronMax->text().toAscii())/100.0; 
+	upperBound[4] = atof(lineEdit_rudderMax->text().toAscii())/100.0; 
+	upperBound[5] = atof(lineEdit_betaMax->text().toAscii())*M_PI/180.0; 
+
+	initialGuess[0] = atof(lineEdit_throttleGuess->text().toAscii())/100.0; 
+	initialGuess[1] = atof(lineEdit_elevatorGuess->text().toAscii())/100.0; 
+	initialGuess[2] = atof(lineEdit_alphaGuess->text().toAscii())*M_PI/180.0; 
+	initialGuess[3] = atof(lineEdit_aileronGuess->text().toAscii())/100.0; 
+	initialGuess[4] = atof(lineEdit_rudderGuess->text().toAscii())/100.0; 
+	initialGuess[5] = atof(lineEdit_betaGuess->text().toAscii())*M_PI/180.0; 
+
+	initialStepSize[0] = atof(lineEdit_throttleInitialStepSize->text().toAscii())/100.0; 
+	initialStepSize[1] = atof(lineEdit_elevatorInitialStepSize->text().toAscii())/100.0; 
+	initialStepSize[2] = atof(lineEdit_alphaInitialStepSize->text().toAscii())*M_PI/180.0; 
+	initialStepSize[3] = atof(lineEdit_aileronInitialStepSize->text().toAscii())/100.0; 
+	initialStepSize[4] = atof(lineEdit_rudderInitialStepSize->text().toAscii())/100.0; 
+	initialStepSize[5] = atof(lineEdit_betaInitialStepSize->text().toAscii())*M_PI/180.0; 
+
+	// loading
+	std::cout << "\n==============================================\n";
+	std::cout << "\tJSBSim Trimming Utility\n";
+	std::cout << "==============================================\n" << std::endl;
+
+	fdm->Setdt(dt);
+
+	if (!fdm->LoadModel(aircraftPath,enginePath,systemsPath,aircraft,false))
+	{
+		showMsgBuffered("model paths incorrect");
+		return;
+	}
+	std::string aircraftName = fdm->GetAircraft()->GetAircraftName();
+	std::cout << "\tsuccessfully loaded: " <<  aircraftName << std::endl;
+
+	// Turn on propulsion system
+	fdm->GetPropulsion()->InitRunning(-1);
+
+	// get propulsion pointer to determine type/ etc.
+	FGEngine * engine0 = fdm->GetPropulsion()->GetEngine(0);
+	FGThruster * thruster0 = engine0->GetThruster();
+
+	
+	// solve
+	trimmer = new FGTrimmer(*fdm,constraints);
+	FGNelderMead solver(*trimmer,initialGuess, lowerBound, upperBound, initialStepSize,
+						iterMax,rtol,abstol,speed, random, showConvergeStatus,showSimplex,pause,callback);
+	stopRequested = false;
+	while(!stopRequested && solver.status()==1) solver.update();
+
+	if (stopRequested) return;
+	else if (solver.status()!=0)
+	{
+		showMsgBuffered("solver failed");
+		return;
+	}
+
+	showMsgBuffered("solver converged");
+
+	// output
+	trimmer->printSolution(solver.getSolution()); // this also loads the solution into the fdm
+
+	//std::cout << "\nsimulating flight to determine trim stability" << std::endl;
+
+	//std::cout << "\nt = 5 seconds" << std::endl;
+	//for (int i=0;i<5*120;i++) fdm.Run();
+	//trimmer->printState();
+
+	//std::cout << "\nt = 10 seconds" << std::endl;
+	//for (int i=0;i<5*120;i++) fdm.Run();
+	//trimmer->printState();
+
+	ss = new FGStateSpace(*fdm);
+
+	// longitudinal states
+	ss->x.add(new FGStateSpace::Vt); 	// 0 
+	ss->x.add(new FGStateSpace::Alpha); // 1
+	ss->x.add(new FGStateSpace::Theta); // 2
+	ss->x.add(new FGStateSpace::Q); 	// 3
+	ss->x.add(new FGStateSpace::Alt); 	// 4
+
+	// lateral states
+	ss->x.add(new FGStateSpace::Beta);  // 5
+	ss->x.add(new FGStateSpace::Phi); 	// 6
+	ss->x.add(new FGStateSpace::P); 	// 7
+	ss->x.add(new FGStateSpace::R); 	// 8
+	ss->x.add(new FGStateSpace::Psi); 	// 9
+
+	// nav states
+	ss->x.add(new FGStateSpace::Longitude); // 10
+	ss->x.add(new FGStateSpace::Latitude); // 11
+
+	// propulsion states
+	if (thruster0->GetType()==FGThruster::ttPropeller)
+    {
+        ss->x.add(new FGStateSpace::Rpm0);
+        if (variablePropPitch) ss->x.add(new FGStateSpace::PropPitch);
+		int numEngines = fdm->GetPropulsion()->GetNumEngines();
+		if (numEngines>1) ss->x.add(new FGStateSpace::Rpm1);
+		if (numEngines>2) ss->x.add(new FGStateSpace::Rpm2);
+		if (numEngines>3) ss->x.add(new FGStateSpace::Rpm3);
+    }
+
+	// input
+	ss->u.add(new FGStateSpace::ThrottleCmd); 	// 0
+	ss->u.add(new FGStateSpace::DaCmd); 		// 1
+	ss->u.add(new FGStateSpace::DeCmd); 		// 2
+	ss->u.add(new FGStateSpace::DrCmd); 		// 3
+
+	// state feedback
+	ss->y = ss->x;
+}
+
+void MainWindow::simulate()
+{
+	if (!fdm) return;
+	QMutexLocker locker(&fdmMutex);
+	fdm->Run();
+	double maxDeflection = 20.0*3.14/180.0; // TODO: this is rough
+	viewer->mutex.lock();
+	plane->setEuler(ss->x.get(6),ss->x.get(2),ss->x.get(9));
+	plane->setU(ss->u.get(0),ss->u.get(1)*maxDeflection,
+			ss->u.get(2)*maxDeflection,ss->u.get(3)*maxDeflection);
+	viewer->mutex.unlock();
+}
+
+SimulateThread::SimulateThread(MainWindow * window) : window(window), timer(this)
+{
+	connect(&timer, SIGNAL(timeout()), window, SLOT(simulate()));
+}
+void SimulateThread::run()
+{
+	using namespace JSBSim;
+	std::cout << "simulation started" << std::endl;
+	timer.start(1000/120);
+	exec();
+}
+
+
+TrimThread::TrimThread(MainWindow * window) : window(window)
+{
+}
+
+void TrimThread::run()
+{
+	try
+	{
+		window->trim();
+	}
+	catch(std::exception & e)
+	{
+		std::cerr << "exception: " << e.what() << std::endl;
+		window->showMsgBuffered(e.what());
+	}
+}
+
+// vim:ts=4:sw=4
diff --git a/gui/MainWindow.hpp b/gui/MainWindow.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..45963d254328b8cc0b0639d2a59110c5e7da982e
--- /dev/null
+++ b/gui/MainWindow.hpp
@@ -0,0 +1,140 @@
+/*
+ * MainWindow.hpp
+ * Copyright (C) James Goppert 2010 <james.goppert@gmail.com>
+ *
+ * MainWindow.hpp is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MainWindow.hpp is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MainWindow_HPP
+#define MainWindow_HPP
+
+#include <QWidget>
+#include "MainWindow.ui.h"
+#include "osgUtils.hpp"
+#include "math/FGNelderMead.h"
+#include <iomanip>
+#include <QThread>
+#include <QSettings>
+//#include "config.h"
+#include <stdexcept>
+#include <math/FGStateSpace.h>
+#include <initialization/FGTrimmer.h>
+#include <QMutex>
+
+class MainWindow;
+
+class SimulateThread : public QThread
+{
+	Q_OBJECT
+public:
+	
+	SimulateThread(MainWindow * window);
+	void run();
+	MainWindow * window;
+	QTimer timer;
+	void quit()
+	{
+		timer.stop();
+		QThread::quit();
+	}
+};
+
+class TrimThread : public QThread
+{
+	Q_OBJECT
+public:
+	TrimThread(MainWindow * window);
+	void run();
+	MainWindow * window;
+};
+
+class MainWindow : public QMainWindow, private Ui::MainWindow
+{
+    Q_OBJECT
+	friend class SimulateThread;
+	friend class TrimThread;
+public:
+    MainWindow();
+    virtual ~MainWindow();
+	QMutex fdmMutex;
+
+signals:
+	void showMsgBuffered(const QString & str);
+
+private slots:
+    void on_toolButton_enginePath_pressed();
+    void on_toolButton_systemsPath_pressed();
+    void on_toolButton_aircraftPath_pressed();
+    void on_toolButton_aircraft_pressed();
+    void on_toolButton_initScript_pressed();
+    void on_pushButton_trim_pressed();
+    void on_pushButton_stop_pressed();
+    void on_pushButton_linearize_pressed();
+    void on_pushButton_simulate_pressed();
+	void showMsg(const QString & str);
+	void simulate();
+	void trim();
+
+private:
+	class SolverCallback : public JSBSim::FGNelderMead::Callback
+	{
+	public:
+		SolverCallback(MainWindow * window) : window(window)
+		{
+		}
+		void eval(const std::vector<double> & v)
+		{
+			double maxDeflection = 20.0*3.14/180.0; // TODO: this is rough
+				// should depend on aircraft, but currently no access
+			std::vector<double> data = window->trimmer->constrain(v);
+			window->viewer->mutex.lock();
+			window->plane->setEuler(data[0],data[1],v[5]);
+				// phi, theta, beta to show orient, and side slip
+			window->plane->setU(v[0],v[3]*maxDeflection,
+					v[1]*maxDeflection,v[4]*maxDeflection);
+			window->viewer->mutex.unlock();
+		}
+		MainWindow * window;
+	};
+	SimulateThread simThread;
+	TrimThread trimThread;
+	SolverCallback * callback;
+	    osg::ref_ptr<osg::Group> sceneRoot;
+    void loadModel(const std::string & name);
+
+	void stopSolver();
+	volatile bool stopRequested;
+    template <class varType>
+    void prompt(const std::string & str, varType & var)
+    {
+        std::cout << str + " [" << std::setw(10) << var << "]\t: ";
+        if (std::cin.peek() != '\n')
+        {
+            std::cin >> var;
+            std::cin.ignore(1000, '\n');
+        }
+        else std::cin.get();
+    }
+	QSettings * settings;
+	void writeSettings();
+	void readSettings();
+    mavsim::visualization::Plane * plane;
+	JSBSim::FGStateSpace * ss;
+	JSBSim::FGTrimmer * trimmer;
+	JSBSim::FGFDMExec * fdm;
+};
+
+#endif
+
+// vim:ts=4:sw=4
diff --git a/gui/MainWindow.moc.cpp b/gui/MainWindow.moc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6ef6dc00dcc04f0cf2ba78ee64e985261eae9d12
--- /dev/null
+++ b/gui/MainWindow.moc.cpp
@@ -0,0 +1,220 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'MainWindow.hpp'
+**
+** Created: Tue Aug 16 21:04:18 2011
+**      by: The Qt Meta Object Compiler version 62 (Qt 4.7.3)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "MainWindow.hpp"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'MainWindow.hpp' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 62
+#error "This file was generated using the moc from 4.7.3. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+static const uint qt_meta_data_SimulateThread[] = {
+
+ // content:
+       5,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       0,    0, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       0,       // signalCount
+
+       0        // eod
+};
+
+static const char qt_meta_stringdata_SimulateThread[] = {
+    "SimulateThread\0"
+};
+
+const QMetaObject SimulateThread::staticMetaObject = {
+    { &QThread::staticMetaObject, qt_meta_stringdata_SimulateThread,
+      qt_meta_data_SimulateThread, 0 }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &SimulateThread::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *SimulateThread::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *SimulateThread::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_SimulateThread))
+        return static_cast<void*>(const_cast< SimulateThread*>(this));
+    return QThread::qt_metacast(_clname);
+}
+
+int SimulateThread::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QThread::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    return _id;
+}
+static const uint qt_meta_data_TrimThread[] = {
+
+ // content:
+       5,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       0,    0, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       0,       // signalCount
+
+       0        // eod
+};
+
+static const char qt_meta_stringdata_TrimThread[] = {
+    "TrimThread\0"
+};
+
+const QMetaObject TrimThread::staticMetaObject = {
+    { &QThread::staticMetaObject, qt_meta_stringdata_TrimThread,
+      qt_meta_data_TrimThread, 0 }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &TrimThread::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *TrimThread::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *TrimThread::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_TrimThread))
+        return static_cast<void*>(const_cast< TrimThread*>(this));
+    return QThread::qt_metacast(_clname);
+}
+
+int TrimThread::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QThread::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    return _id;
+}
+static const uint qt_meta_data_MainWindow[] = {
+
+ // content:
+       5,       // revision
+       0,       // classname
+       0,    0, // classinfo
+      13,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       1,       // signalCount
+
+ // signals: signature, parameters, type, tag, flags
+      16,   12,   11,   11, 0x05,
+
+ // slots: signature, parameters, type, tag, flags
+      41,   11,   11,   11, 0x08,
+      76,   11,   11,   11, 0x08,
+     112,   11,   11,   11, 0x08,
+     149,   11,   11,   11, 0x08,
+     182,   11,   11,   11, 0x08,
+     217,   11,   11,   11, 0x08,
+     246,   11,   11,   11, 0x08,
+     275,   11,   11,   11, 0x08,
+     309,   11,   11,   11, 0x08,
+     342,   12,   11,   11, 0x08,
+     359,   11,   11,   11, 0x08,
+     370,   11,   11,   11, 0x08,
+
+       0        // eod
+};
+
+static const char qt_meta_stringdata_MainWindow[] = {
+    "MainWindow\0\0str\0showMsgBuffered(QString)\0"
+    "on_toolButton_enginePath_pressed()\0"
+    "on_toolButton_systemsPath_pressed()\0"
+    "on_toolButton_aircraftPath_pressed()\0"
+    "on_toolButton_aircraft_pressed()\0"
+    "on_toolButton_initScript_pressed()\0"
+    "on_pushButton_trim_pressed()\0"
+    "on_pushButton_stop_pressed()\0"
+    "on_pushButton_linearize_pressed()\0"
+    "on_pushButton_simulate_pressed()\0"
+    "showMsg(QString)\0simulate()\0trim()\0"
+};
+
+const QMetaObject MainWindow::staticMetaObject = {
+    { &QMainWindow::staticMetaObject, qt_meta_stringdata_MainWindow,
+      qt_meta_data_MainWindow, 0 }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &MainWindow::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *MainWindow::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *MainWindow::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_MainWindow))
+        return static_cast<void*>(const_cast< MainWindow*>(this));
+    return QMainWindow::qt_metacast(_clname);
+}
+
+int MainWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QMainWindow::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        switch (_id) {
+        case 0: showMsgBuffered((*reinterpret_cast< const QString(*)>(_a[1]))); break;
+        case 1: on_toolButton_enginePath_pressed(); break;
+        case 2: on_toolButton_systemsPath_pressed(); break;
+        case 3: on_toolButton_aircraftPath_pressed(); break;
+        case 4: on_toolButton_aircraft_pressed(); break;
+        case 5: on_toolButton_initScript_pressed(); break;
+        case 6: on_pushButton_trim_pressed(); break;
+        case 7: on_pushButton_stop_pressed(); break;
+        case 8: on_pushButton_linearize_pressed(); break;
+        case 9: on_pushButton_simulate_pressed(); break;
+        case 10: showMsg((*reinterpret_cast< const QString(*)>(_a[1]))); break;
+        case 11: simulate(); break;
+        case 12: trim(); break;
+        default: ;
+        }
+        _id -= 13;
+    }
+    return _id;
+}
+
+// SIGNAL 0
+void MainWindow::showMsgBuffered(const QString & _t1)
+{
+    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
+    QMetaObject::activate(this, &staticMetaObject, 0, _a);
+}
+QT_END_MOC_NAMESPACE
diff --git a/gui/MainWindow.ui b/gui/MainWindow.ui
new file mode 100644
index 0000000000000000000000000000000000000000..5b96bbe8663452d10f8fb31569dd255b8d13a08f
--- /dev/null
+++ b/gui/MainWindow.ui
@@ -0,0 +1,917 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>825</width>
+    <height>862</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Ignored" vsizetype="Ignored">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle">
+   <string>mavsim Trim Program (for JSBSim models)</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QGridLayout" name="gridLayout">
+    <item row="0" column="0" colspan="4">
+     <widget class="ViewerQT" name="viewer" native="true">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Ignored" vsizetype="Ignored">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="0">
+     <widget class="QPushButton" name="pushButton_trim">
+      <property name="text">
+       <string>Trim</string>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="3">
+     <widget class="QPushButton" name="pushButton_simulate">
+      <property name="text">
+       <string>Simulate</string>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="2">
+     <widget class="QPushButton" name="pushButton_linearize">
+      <property name="text">
+       <string>Linearize</string>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="1">
+     <widget class="QPushButton" name="pushButton_stop">
+      <property name="text">
+       <string>Stop</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+  <widget class="QDockWidget" name="guidanceDock">
+   <property name="sizePolicy">
+    <sizepolicy hsizetype="Ignored" vsizetype="Ignored">
+     <horstretch>0</horstretch>
+     <verstretch>0</verstretch>
+    </sizepolicy>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>685</width>
+     <height>446</height>
+    </size>
+   </property>
+   <property name="windowTitle">
+    <string>Trim Algorithm</string>
+   </property>
+   <attribute name="dockWidgetArea">
+    <number>8</number>
+   </attribute>
+   <widget class="QWidget" name="dockWidgetContents_6">
+    <layout class="QGridLayout" name="gridLayout_4">
+     <item row="0" column="0">
+      <widget class="QTabWidget" name="tabWidget">
+       <property name="currentIndex">
+        <number>5</number>
+       </property>
+       <widget class="QWidget" name="tab_3">
+        <attribute name="title">
+         <string>Aircraft</string>
+        </attribute>
+        <layout class="QGridLayout" name="gridLayout_5">
+         <item row="1" column="1">
+          <widget class="QLabel" name="label_2">
+           <property name="text">
+            <string>Engine Path</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2">
+          <widget class="QLineEdit" name="lineEdit_enginePath">
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLabel" name="label_4">
+           <property name="text">
+            <string>Systems Path</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1">
+          <widget class="QLabel" name="label_3">
+           <property name="text">
+            <string>Aircraft Path</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="2">
+          <widget class="QLineEdit" name="lineEdit_systemsPath">
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="3">
+          <widget class="QToolButton" name="toolButton_enginePath">
+           <property name="text">
+            <string>...</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="3">
+          <widget class="QToolButton" name="toolButton_systemsPath">
+           <property name="text">
+            <string>...</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="3">
+          <widget class="QToolButton" name="toolButton_aircraftPath">
+           <property name="text">
+            <string>...</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="1">
+          <widget class="QLabel" name="label_9">
+           <property name="text">
+            <string>Aircraft</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="2">
+          <widget class="QLineEdit" name="lineEdit_aircraft">
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="3">
+          <widget class="QToolButton" name="toolButton_aircraft">
+           <property name="text">
+            <string>...</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="1">
+          <widget class="QLabel" name="label_5">
+           <property name="text">
+            <string>Initialization Script</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="2">
+          <widget class="QLineEdit" name="lineEdit_initScript">
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="3">
+          <widget class="QToolButton" name="toolButton_initScript">
+           <property name="text">
+            <string>...</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="2">
+          <widget class="QLineEdit" name="lineEdit_aircraftPath">
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QLabel" name="label_38">
+           <property name="text">
+            <string>model sim rate</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="2">
+          <widget class="QLineEdit" name="lineEdit_modelSimRate">
+           <property name="text">
+            <string>120</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="3">
+          <widget class="QLabel" name="label_39">
+           <property name="text">
+            <string>Hz</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+       <widget class="QWidget" name="tab">
+        <attribute name="title">
+         <string>Trim Conditions</string>
+        </attribute>
+        <layout class="QGridLayout" name="gridLayout_2">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_10">
+           <property name="text">
+            <string>mode</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1" colspan="6">
+          <widget class="QComboBox" name="comboBox_mode">
+           <item>
+            <property name="text">
+             <string>Steady Level Flight</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Coordinated Turn</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Push Over</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Pull Back</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label">
+           <property name="text">
+            <string>velocity</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1" colspan="5">
+          <widget class="QLineEdit" name="lineEdit_velocity">
+           <property name="text">
+            <string>500</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="6">
+          <widget class="QLabel" name="label_11">
+           <property name="text">
+            <string>ft/s</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="label_6">
+           <property name="text">
+            <string>roll rate</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1" colspan="5">
+          <widget class="QLineEdit" name="lineEdit_rollRate">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="6">
+          <widget class="QLabel" name="label_12">
+           <property name="text">
+            <string>rad/s</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="0">
+          <widget class="QLabel" name="label_7">
+           <property name="text">
+            <string>pitch rate</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1" colspan="5">
+          <widget class="QLineEdit" name="lineEdit_pitchRate">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="6">
+          <widget class="QLabel" name="label_13">
+           <property name="text">
+            <string>rad/s</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="0">
+          <widget class="QLabel" name="label_8">
+           <property name="text">
+            <string>yaw rate</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="6">
+          <widget class="QLabel" name="label_14">
+           <property name="text">
+            <string>rad/s</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="1" colspan="5">
+          <widget class="QLineEdit" name="lineEdit_yawRate">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="8" column="0">
+          <widget class="QCheckBox" name="checkBox_stabAxisRoll">
+           <property name="text">
+            <string>stability axis roll</string>
+           </property>
+           <property name="checkable">
+            <bool>true</bool>
+           </property>
+           <property name="checked">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="0">
+          <widget class="QLabel" name="label_40">
+           <property name="text">
+            <string>altitude</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="1" colspan="5">
+          <widget class="QLineEdit" name="lineEdit_altitude">
+           <property name="text">
+            <string>1000</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="6">
+          <widget class="QLabel" name="label_41">
+           <property name="text">
+            <string>ft</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="0">
+          <widget class="QLabel" name="label_42">
+           <property name="text">
+            <string>flight path angle</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="1" colspan="5">
+          <widget class="QLineEdit" name="lineEdit_gamma">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="0">
+          <widget class="QCheckBox" name="checkBox_variablePropPitch">
+           <property name="text">
+            <string>variable prop ptich</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="6">
+          <widget class="QLabel" name="label_43">
+           <property name="text">
+            <string>deg</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+       <widget class="QWidget" name="tab_2">
+        <attribute name="title">
+         <string>Solver</string>
+        </attribute>
+        <layout class="QGridLayout" name="gridLayout_6">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_20">
+           <property name="text">
+            <string>relative tolerance</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_21">
+           <property name="text">
+            <string>absolute tolerance</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="label_22">
+           <property name="text">
+            <string>convergence relative step size</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="0">
+          <widget class="QLabel" name="label_23">
+           <property name="text">
+            <string>max iterations</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1" colspan="2">
+          <widget class="QLineEdit" name="lineEdit_abstol">
+           <property name="text">
+            <string>1e-2</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1" colspan="2">
+          <widget class="QLineEdit" name="lineEdit_speed">
+           <property name="text">
+            <string>1.1</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1" colspan="2">
+          <widget class="QLineEdit" name="lineEdit_iterMax">
+           <property name="text">
+            <string>2000</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="1" colspan="2">
+          <widget class="QComboBox" name="comboBox_debugLevel">
+           <item>
+            <property name="text">
+             <string>0</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>1</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>2</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+         <item row="4" column="0">
+          <widget class="QLabel" name="label_34">
+           <property name="text">
+            <string>debug level</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="0">
+          <widget class="QCheckBox" name="checkBox_pause">
+           <property name="text">
+            <string>pause </string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1" colspan="2">
+          <widget class="QLineEdit" name="lineEdit_rtol">
+           <property name="text">
+            <string>1e-4</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="1">
+          <widget class="QCheckBox" name="checkBox_showSimplex">
+           <property name="text">
+            <string>show simplex</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="2">
+          <widget class="QCheckBox" name="checkBox_showConvergence">
+           <property name="text">
+            <string>show convergence</string>
+           </property>
+           <property name="checked">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="0">
+          <widget class="QLabel" name="label_44">
+           <property name="text">
+            <string>randomization factor</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="1">
+          <widget class="QLineEdit" name="lineEdit_random">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+       <widget class="QWidget" name="tab_6">
+        <attribute name="title">
+         <string>Input</string>
+        </attribute>
+        <layout class="QGridLayout" name="gridLayout_8">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_36">
+           <property name="text">
+            <string>joystick device</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QLineEdit" name="lineEdit_joystick">
+           <property name="text">
+            <string>/dev/input/js0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="2">
+          <widget class="QToolButton" name="toolButton">
+           <property name="text">
+            <string>...</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0" colspan="2">
+          <widget class="QCheckBox" name="checkBox_joystickEnabled">
+           <property name="text">
+            <string>joystick enabled</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+       <widget class="QWidget" name="tab_4">
+        <attribute name="title">
+         <string>Initial Guess</string>
+        </attribute>
+        <layout class="QGridLayout" name="gridLayout_7">
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_15">
+           <property name="text">
+            <string>Throttle</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="0">
+          <widget class="QLabel" name="label_17">
+           <property name="text">
+            <string>Alpha</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="0">
+          <widget class="QLabel" name="label_19">
+           <property name="text">
+            <string>Beta</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="lineEdit_throttleGuess">
+           <property name="text">
+            <string>50</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1">
+          <widget class="QLineEdit" name="lineEdit_aileronGuess">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="1">
+          <widget class="QLineEdit" name="lineEdit_elevatorGuess">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="1">
+          <widget class="QLineEdit" name="lineEdit_alphaGuess">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="1">
+          <widget class="QLineEdit" name="lineEdit_betaGuess">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="5">
+          <widget class="QLabel" name="label_24">
+           <property name="text">
+            <string>%</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="5">
+          <widget class="QLabel" name="label_25">
+           <property name="text">
+            <string>%</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="5">
+          <widget class="QLabel" name="label_26">
+           <property name="text">
+            <string>%</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="5">
+          <widget class="QLabel" name="label_27">
+           <property name="text">
+            <string>deg</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="5">
+          <widget class="QLabel" name="label_28">
+           <property name="text">
+            <string>deg</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2">
+          <widget class="QLineEdit" name="lineEdit_throttleMin">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="2">
+          <widget class="QLineEdit" name="lineEdit_aileronMin">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="2">
+          <widget class="QLineEdit" name="lineEdit_elevatorMin">
+           <property name="text">
+            <string>-100</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="2">
+          <widget class="QLineEdit" name="lineEdit_alphaMin">
+           <property name="text">
+            <string>-10</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="2">
+          <widget class="QLineEdit" name="lineEdit_betaMin">
+           <property name="text">
+            <string>-10</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QLabel" name="label_29">
+           <property name="text">
+            <string>Guess</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="2">
+          <widget class="QLabel" name="label_30">
+           <property name="text">
+            <string>Lower Bound</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="3">
+          <widget class="QLineEdit" name="lineEdit_throttleMax">
+           <property name="text">
+            <string>100</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="3">
+          <widget class="QLineEdit" name="lineEdit_aileronMax">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="3">
+          <widget class="QLineEdit" name="lineEdit_elevatorMax">
+           <property name="text">
+            <string>100</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="3">
+          <widget class="QLineEdit" name="lineEdit_alphaMax">
+           <property name="text">
+            <string>20</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="3">
+          <widget class="QLineEdit" name="lineEdit_betaMax">
+           <property name="text">
+            <string>5</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="3">
+          <widget class="QLabel" name="label_31">
+           <property name="text">
+            <string>Upper Bound</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="0">
+          <widget class="QLabel" name="label_16">
+           <property name="text">
+            <string>Elevator</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="0">
+          <widget class="QLabel" name="label_18">
+           <property name="text">
+            <string>Aileron</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="0">
+          <widget class="QLabel" name="label_32">
+           <property name="text">
+            <string>Rudder</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="1">
+          <widget class="QLineEdit" name="lineEdit_rudderGuess">
+           <property name="text">
+            <string>0</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="2">
+          <widget class="QLineEdit" name="lineEdit_rudderMin">
+           <property name="text">
+            <string>-100</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="3">
+          <widget class="QLineEdit" name="lineEdit_rudderMax">
+           <property name="text">
+            <string>100</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="5">
+          <widget class="QLabel" name="label_33">
+           <property name="text">
+            <string>%</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="4">
+          <widget class="QLineEdit" name="lineEdit_throttleInitialStepSize">
+           <property name="text">
+            <string>20</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="4">
+          <widget class="QLineEdit" name="lineEdit_aileronInitialStepSize">
+           <property name="text">
+            <string>10</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="4">
+          <widget class="QLineEdit" name="lineEdit_rudderInitialStepSize">
+           <property name="text">
+            <string>10</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="4">
+          <widget class="QLineEdit" name="lineEdit_elevatorInitialStepSize">
+           <property name="text">
+            <string>10</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="4">
+          <widget class="QLineEdit" name="lineEdit_alphaInitialStepSize">
+           <property name="text">
+            <string>10</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="4">
+          <widget class="QLineEdit" name="lineEdit_betaInitialStepSize">
+           <property name="text">
+            <string>5</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="4">
+          <widget class="QLabel" name="label_37">
+           <property name="text">
+            <string>Initial Step Size</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+       <widget class="QWidget" name="tab_5">
+        <attribute name="title">
+         <string>Output</string>
+        </attribute>
+        <layout class="QGridLayout" name="gridLayout_3">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_35">
+           <property name="text">
+            <string>Linearization File</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QLineEdit" name="lineEdit_linearizationFile"/>
+         </item>
+        </layout>
+       </widget>
+      </widget>
+     </item>
+    </layout>
+   </widget>
+  </widget>
+  <action name="actionQuit">
+   <property name="text">
+    <string>Quit</string>
+   </property>
+  </action>
+  <action name="actionLoad_Map">
+   <property name="text">
+    <string>Load Map</string>
+   </property>
+  </action>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>ViewerQT</class>
+   <extends>QWidget</extends>
+   <header>QOSGAdapterWidget.hpp</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>actionQuit</sender>
+   <signal>triggered()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>311</x>
+     <y>461</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/gui/MainWindow.ui.h b/gui/MainWindow.ui.h
new file mode 100644
index 0000000000000000000000000000000000000000..d051039c3abaf655474a34e6b18a651c3d9dabdd
--- /dev/null
+++ b/gui/MainWindow.ui.h
@@ -0,0 +1,915 @@
+/********************************************************************************
+** Form generated from reading UI file 'MainWindow.ui'
+**
+** Created: Tue Aug 16 20:52:00 2011
+**      by: Qt User Interface Compiler version 4.7.3
+**
+** WARNING! All changes made in this file will be lost when recompiling UI file!
+********************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QCheckBox>
+#include <QtGui/QComboBox>
+#include <QtGui/QDockWidget>
+#include <QtGui/QGridLayout>
+#include <QtGui/QHeaderView>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QMainWindow>
+#include <QtGui/QPushButton>
+#include <QtGui/QStatusBar>
+#include <QtGui/QTabWidget>
+#include <QtGui/QToolButton>
+#include <QtGui/QWidget>
+#include "QOSGAdapterWidget.hpp"
+
+QT_BEGIN_NAMESPACE
+
+class Ui_MainWindow
+{
+public:
+    QAction *actionQuit;
+    QAction *actionLoad_Map;
+    QWidget *centralwidget;
+    QGridLayout *gridLayout;
+    ViewerQT *viewer;
+    QPushButton *pushButton_trim;
+    QPushButton *pushButton_simulate;
+    QPushButton *pushButton_linearize;
+    QPushButton *pushButton_stop;
+    QStatusBar *statusbar;
+    QDockWidget *guidanceDock;
+    QWidget *dockWidgetContents_6;
+    QGridLayout *gridLayout_4;
+    QTabWidget *tabWidget;
+    QWidget *tab_3;
+    QGridLayout *gridLayout_5;
+    QLabel *label_2;
+    QLineEdit *lineEdit_enginePath;
+    QLabel *label_4;
+    QLabel *label_3;
+    QLineEdit *lineEdit_systemsPath;
+    QToolButton *toolButton_enginePath;
+    QToolButton *toolButton_systemsPath;
+    QToolButton *toolButton_aircraftPath;
+    QLabel *label_9;
+    QLineEdit *lineEdit_aircraft;
+    QToolButton *toolButton_aircraft;
+    QLabel *label_5;
+    QLineEdit *lineEdit_initScript;
+    QToolButton *toolButton_initScript;
+    QLineEdit *lineEdit_aircraftPath;
+    QLabel *label_38;
+    QLineEdit *lineEdit_modelSimRate;
+    QLabel *label_39;
+    QWidget *tab;
+    QGridLayout *gridLayout_2;
+    QLabel *label_10;
+    QComboBox *comboBox_mode;
+    QLabel *label;
+    QLineEdit *lineEdit_velocity;
+    QLabel *label_11;
+    QLabel *label_6;
+    QLineEdit *lineEdit_rollRate;
+    QLabel *label_12;
+    QLabel *label_7;
+    QLineEdit *lineEdit_pitchRate;
+    QLabel *label_13;
+    QLabel *label_8;
+    QLabel *label_14;
+    QLineEdit *lineEdit_yawRate;
+    QCheckBox *checkBox_stabAxisRoll;
+    QLabel *label_40;
+    QLineEdit *lineEdit_altitude;
+    QLabel *label_41;
+    QLabel *label_42;
+    QLineEdit *lineEdit_gamma;
+    QCheckBox *checkBox_variablePropPitch;
+    QLabel *label_43;
+    QWidget *tab_2;
+    QGridLayout *gridLayout_6;
+    QLabel *label_20;
+    QLabel *label_21;
+    QLabel *label_22;
+    QLabel *label_23;
+    QLineEdit *lineEdit_abstol;
+    QLineEdit *lineEdit_speed;
+    QLineEdit *lineEdit_iterMax;
+    QComboBox *comboBox_debugLevel;
+    QLabel *label_34;
+    QCheckBox *checkBox_pause;
+    QLineEdit *lineEdit_rtol;
+    QCheckBox *checkBox_showSimplex;
+    QCheckBox *checkBox_showConvergence;
+    QLabel *label_44;
+    QLineEdit *lineEdit_random;
+    QWidget *tab_6;
+    QGridLayout *gridLayout_8;
+    QLabel *label_36;
+    QLineEdit *lineEdit_joystick;
+    QToolButton *toolButton;
+    QCheckBox *checkBox_joystickEnabled;
+    QWidget *tab_4;
+    QGridLayout *gridLayout_7;
+    QLabel *label_15;
+    QLabel *label_17;
+    QLabel *label_19;
+    QLineEdit *lineEdit_throttleGuess;
+    QLineEdit *lineEdit_aileronGuess;
+    QLineEdit *lineEdit_elevatorGuess;
+    QLineEdit *lineEdit_alphaGuess;
+    QLineEdit *lineEdit_betaGuess;
+    QLabel *label_24;
+    QLabel *label_25;
+    QLabel *label_26;
+    QLabel *label_27;
+    QLabel *label_28;
+    QLineEdit *lineEdit_throttleMin;
+    QLineEdit *lineEdit_aileronMin;
+    QLineEdit *lineEdit_elevatorMin;
+    QLineEdit *lineEdit_alphaMin;
+    QLineEdit *lineEdit_betaMin;
+    QLabel *label_29;
+    QLabel *label_30;
+    QLineEdit *lineEdit_throttleMax;
+    QLineEdit *lineEdit_aileronMax;
+    QLineEdit *lineEdit_elevatorMax;
+    QLineEdit *lineEdit_alphaMax;
+    QLineEdit *lineEdit_betaMax;
+    QLabel *label_31;
+    QLabel *label_16;
+    QLabel *label_18;
+    QLabel *label_32;
+    QLineEdit *lineEdit_rudderGuess;
+    QLineEdit *lineEdit_rudderMin;
+    QLineEdit *lineEdit_rudderMax;
+    QLabel *label_33;
+    QLineEdit *lineEdit_throttleInitialStepSize;
+    QLineEdit *lineEdit_aileronInitialStepSize;
+    QLineEdit *lineEdit_rudderInitialStepSize;
+    QLineEdit *lineEdit_elevatorInitialStepSize;
+    QLineEdit *lineEdit_alphaInitialStepSize;
+    QLineEdit *lineEdit_betaInitialStepSize;
+    QLabel *label_37;
+    QWidget *tab_5;
+    QGridLayout *gridLayout_3;
+    QLabel *label_35;
+    QLineEdit *lineEdit_linearizationFile;
+
+    void setupUi(QMainWindow *MainWindow)
+    {
+        if (MainWindow->objectName().isEmpty())
+            MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
+        MainWindow->resize(825, 862);
+        QSizePolicy sizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+        sizePolicy.setHorizontalStretch(0);
+        sizePolicy.setVerticalStretch(0);
+        sizePolicy.setHeightForWidth(MainWindow->sizePolicy().hasHeightForWidth());
+        MainWindow->setSizePolicy(sizePolicy);
+        actionQuit = new QAction(MainWindow);
+        actionQuit->setObjectName(QString::fromUtf8("actionQuit"));
+        actionLoad_Map = new QAction(MainWindow);
+        actionLoad_Map->setObjectName(QString::fromUtf8("actionLoad_Map"));
+        centralwidget = new QWidget(MainWindow);
+        centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
+        gridLayout = new QGridLayout(centralwidget);
+        gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+        viewer = new ViewerQT(centralwidget);
+        viewer->setObjectName(QString::fromUtf8("viewer"));
+        sizePolicy.setHeightForWidth(viewer->sizePolicy().hasHeightForWidth());
+        viewer->setSizePolicy(sizePolicy);
+
+        gridLayout->addWidget(viewer, 0, 0, 1, 4);
+
+        pushButton_trim = new QPushButton(centralwidget);
+        pushButton_trim->setObjectName(QString::fromUtf8("pushButton_trim"));
+
+        gridLayout->addWidget(pushButton_trim, 1, 0, 1, 1);
+
+        pushButton_simulate = new QPushButton(centralwidget);
+        pushButton_simulate->setObjectName(QString::fromUtf8("pushButton_simulate"));
+
+        gridLayout->addWidget(pushButton_simulate, 1, 3, 1, 1);
+
+        pushButton_linearize = new QPushButton(centralwidget);
+        pushButton_linearize->setObjectName(QString::fromUtf8("pushButton_linearize"));
+
+        gridLayout->addWidget(pushButton_linearize, 1, 2, 1, 1);
+
+        pushButton_stop = new QPushButton(centralwidget);
+        pushButton_stop->setObjectName(QString::fromUtf8("pushButton_stop"));
+
+        gridLayout->addWidget(pushButton_stop, 1, 1, 1, 1);
+
+        MainWindow->setCentralWidget(centralwidget);
+        statusbar = new QStatusBar(MainWindow);
+        statusbar->setObjectName(QString::fromUtf8("statusbar"));
+        MainWindow->setStatusBar(statusbar);
+        guidanceDock = new QDockWidget(MainWindow);
+        guidanceDock->setObjectName(QString::fromUtf8("guidanceDock"));
+        sizePolicy.setHeightForWidth(guidanceDock->sizePolicy().hasHeightForWidth());
+        guidanceDock->setSizePolicy(sizePolicy);
+        guidanceDock->setMinimumSize(QSize(685, 446));
+        dockWidgetContents_6 = new QWidget();
+        dockWidgetContents_6->setObjectName(QString::fromUtf8("dockWidgetContents_6"));
+        gridLayout_4 = new QGridLayout(dockWidgetContents_6);
+        gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4"));
+        tabWidget = new QTabWidget(dockWidgetContents_6);
+        tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
+        tab_3 = new QWidget();
+        tab_3->setObjectName(QString::fromUtf8("tab_3"));
+        gridLayout_5 = new QGridLayout(tab_3);
+        gridLayout_5->setObjectName(QString::fromUtf8("gridLayout_5"));
+        label_2 = new QLabel(tab_3);
+        label_2->setObjectName(QString::fromUtf8("label_2"));
+
+        gridLayout_5->addWidget(label_2, 1, 1, 1, 1);
+
+        lineEdit_enginePath = new QLineEdit(tab_3);
+        lineEdit_enginePath->setObjectName(QString::fromUtf8("lineEdit_enginePath"));
+
+        gridLayout_5->addWidget(lineEdit_enginePath, 1, 2, 1, 1);
+
+        label_4 = new QLabel(tab_3);
+        label_4->setObjectName(QString::fromUtf8("label_4"));
+
+        gridLayout_5->addWidget(label_4, 2, 1, 1, 1);
+
+        label_3 = new QLabel(tab_3);
+        label_3->setObjectName(QString::fromUtf8("label_3"));
+
+        gridLayout_5->addWidget(label_3, 3, 1, 1, 1);
+
+        lineEdit_systemsPath = new QLineEdit(tab_3);
+        lineEdit_systemsPath->setObjectName(QString::fromUtf8("lineEdit_systemsPath"));
+
+        gridLayout_5->addWidget(lineEdit_systemsPath, 2, 2, 1, 1);
+
+        toolButton_enginePath = new QToolButton(tab_3);
+        toolButton_enginePath->setObjectName(QString::fromUtf8("toolButton_enginePath"));
+
+        gridLayout_5->addWidget(toolButton_enginePath, 1, 3, 1, 1);
+
+        toolButton_systemsPath = new QToolButton(tab_3);
+        toolButton_systemsPath->setObjectName(QString::fromUtf8("toolButton_systemsPath"));
+
+        gridLayout_5->addWidget(toolButton_systemsPath, 2, 3, 1, 1);
+
+        toolButton_aircraftPath = new QToolButton(tab_3);
+        toolButton_aircraftPath->setObjectName(QString::fromUtf8("toolButton_aircraftPath"));
+
+        gridLayout_5->addWidget(toolButton_aircraftPath, 3, 3, 1, 1);
+
+        label_9 = new QLabel(tab_3);
+        label_9->setObjectName(QString::fromUtf8("label_9"));
+
+        gridLayout_5->addWidget(label_9, 4, 1, 1, 1);
+
+        lineEdit_aircraft = new QLineEdit(tab_3);
+        lineEdit_aircraft->setObjectName(QString::fromUtf8("lineEdit_aircraft"));
+
+        gridLayout_5->addWidget(lineEdit_aircraft, 4, 2, 1, 1);
+
+        toolButton_aircraft = new QToolButton(tab_3);
+        toolButton_aircraft->setObjectName(QString::fromUtf8("toolButton_aircraft"));
+
+        gridLayout_5->addWidget(toolButton_aircraft, 4, 3, 1, 1);
+
+        label_5 = new QLabel(tab_3);
+        label_5->setObjectName(QString::fromUtf8("label_5"));
+
+        gridLayout_5->addWidget(label_5, 5, 1, 1, 1);
+
+        lineEdit_initScript = new QLineEdit(tab_3);
+        lineEdit_initScript->setObjectName(QString::fromUtf8("lineEdit_initScript"));
+
+        gridLayout_5->addWidget(lineEdit_initScript, 5, 2, 1, 1);
+
+        toolButton_initScript = new QToolButton(tab_3);
+        toolButton_initScript->setObjectName(QString::fromUtf8("toolButton_initScript"));
+
+        gridLayout_5->addWidget(toolButton_initScript, 5, 3, 1, 1);
+
+        lineEdit_aircraftPath = new QLineEdit(tab_3);
+        lineEdit_aircraftPath->setObjectName(QString::fromUtf8("lineEdit_aircraftPath"));
+
+        gridLayout_5->addWidget(lineEdit_aircraftPath, 3, 2, 1, 1);
+
+        label_38 = new QLabel(tab_3);
+        label_38->setObjectName(QString::fromUtf8("label_38"));
+
+        gridLayout_5->addWidget(label_38, 0, 1, 1, 1);
+
+        lineEdit_modelSimRate = new QLineEdit(tab_3);
+        lineEdit_modelSimRate->setObjectName(QString::fromUtf8("lineEdit_modelSimRate"));
+
+        gridLayout_5->addWidget(lineEdit_modelSimRate, 0, 2, 1, 1);
+
+        label_39 = new QLabel(tab_3);
+        label_39->setObjectName(QString::fromUtf8("label_39"));
+
+        gridLayout_5->addWidget(label_39, 0, 3, 1, 1);
+
+        tabWidget->addTab(tab_3, QString());
+        tab = new QWidget();
+        tab->setObjectName(QString::fromUtf8("tab"));
+        gridLayout_2 = new QGridLayout(tab);
+        gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
+        label_10 = new QLabel(tab);
+        label_10->setObjectName(QString::fromUtf8("label_10"));
+
+        gridLayout_2->addWidget(label_10, 0, 0, 1, 1);
+
+        comboBox_mode = new QComboBox(tab);
+        comboBox_mode->setObjectName(QString::fromUtf8("comboBox_mode"));
+
+        gridLayout_2->addWidget(comboBox_mode, 0, 1, 1, 6);
+
+        label = new QLabel(tab);
+        label->setObjectName(QString::fromUtf8("label"));
+
+        gridLayout_2->addWidget(label, 1, 0, 1, 1);
+
+        lineEdit_velocity = new QLineEdit(tab);
+        lineEdit_velocity->setObjectName(QString::fromUtf8("lineEdit_velocity"));
+
+        gridLayout_2->addWidget(lineEdit_velocity, 1, 1, 1, 5);
+
+        label_11 = new QLabel(tab);
+        label_11->setObjectName(QString::fromUtf8("label_11"));
+
+        gridLayout_2->addWidget(label_11, 1, 6, 1, 1);
+
+        label_6 = new QLabel(tab);
+        label_6->setObjectName(QString::fromUtf8("label_6"));
+
+        gridLayout_2->addWidget(label_6, 2, 0, 1, 1);
+
+        lineEdit_rollRate = new QLineEdit(tab);
+        lineEdit_rollRate->setObjectName(QString::fromUtf8("lineEdit_rollRate"));
+
+        gridLayout_2->addWidget(lineEdit_rollRate, 2, 1, 1, 5);
+
+        label_12 = new QLabel(tab);
+        label_12->setObjectName(QString::fromUtf8("label_12"));
+
+        gridLayout_2->addWidget(label_12, 2, 6, 1, 1);
+
+        label_7 = new QLabel(tab);
+        label_7->setObjectName(QString::fromUtf8("label_7"));
+
+        gridLayout_2->addWidget(label_7, 3, 0, 1, 1);
+
+        lineEdit_pitchRate = new QLineEdit(tab);
+        lineEdit_pitchRate->setObjectName(QString::fromUtf8("lineEdit_pitchRate"));
+
+        gridLayout_2->addWidget(lineEdit_pitchRate, 3, 1, 1, 5);
+
+        label_13 = new QLabel(tab);
+        label_13->setObjectName(QString::fromUtf8("label_13"));
+
+        gridLayout_2->addWidget(label_13, 3, 6, 1, 1);
+
+        label_8 = new QLabel(tab);
+        label_8->setObjectName(QString::fromUtf8("label_8"));
+
+        gridLayout_2->addWidget(label_8, 4, 0, 1, 1);
+
+        label_14 = new QLabel(tab);
+        label_14->setObjectName(QString::fromUtf8("label_14"));
+
+        gridLayout_2->addWidget(label_14, 4, 6, 1, 1);
+
+        lineEdit_yawRate = new QLineEdit(tab);
+        lineEdit_yawRate->setObjectName(QString::fromUtf8("lineEdit_yawRate"));
+
+        gridLayout_2->addWidget(lineEdit_yawRate, 4, 1, 1, 5);
+
+        checkBox_stabAxisRoll = new QCheckBox(tab);
+        checkBox_stabAxisRoll->setObjectName(QString::fromUtf8("checkBox_stabAxisRoll"));
+        checkBox_stabAxisRoll->setCheckable(true);
+        checkBox_stabAxisRoll->setChecked(true);
+
+        gridLayout_2->addWidget(checkBox_stabAxisRoll, 8, 0, 1, 1);
+
+        label_40 = new QLabel(tab);
+        label_40->setObjectName(QString::fromUtf8("label_40"));
+
+        gridLayout_2->addWidget(label_40, 5, 0, 1, 1);
+
+        lineEdit_altitude = new QLineEdit(tab);
+        lineEdit_altitude->setObjectName(QString::fromUtf8("lineEdit_altitude"));
+
+        gridLayout_2->addWidget(lineEdit_altitude, 5, 1, 1, 5);
+
+        label_41 = new QLabel(tab);
+        label_41->setObjectName(QString::fromUtf8("label_41"));
+
+        gridLayout_2->addWidget(label_41, 5, 6, 1, 1);
+
+        label_42 = new QLabel(tab);
+        label_42->setObjectName(QString::fromUtf8("label_42"));
+
+        gridLayout_2->addWidget(label_42, 6, 0, 1, 1);
+
+        lineEdit_gamma = new QLineEdit(tab);
+        lineEdit_gamma->setObjectName(QString::fromUtf8("lineEdit_gamma"));
+
+        gridLayout_2->addWidget(lineEdit_gamma, 6, 1, 1, 5);
+
+        checkBox_variablePropPitch = new QCheckBox(tab);
+        checkBox_variablePropPitch->setObjectName(QString::fromUtf8("checkBox_variablePropPitch"));
+
+        gridLayout_2->addWidget(checkBox_variablePropPitch, 7, 0, 1, 1);
+
+        label_43 = new QLabel(tab);
+        label_43->setObjectName(QString::fromUtf8("label_43"));
+
+        gridLayout_2->addWidget(label_43, 6, 6, 1, 1);
+
+        tabWidget->addTab(tab, QString());
+        tab_2 = new QWidget();
+        tab_2->setObjectName(QString::fromUtf8("tab_2"));
+        gridLayout_6 = new QGridLayout(tab_2);
+        gridLayout_6->setObjectName(QString::fromUtf8("gridLayout_6"));
+        label_20 = new QLabel(tab_2);
+        label_20->setObjectName(QString::fromUtf8("label_20"));
+
+        gridLayout_6->addWidget(label_20, 0, 0, 1, 1);
+
+        label_21 = new QLabel(tab_2);
+        label_21->setObjectName(QString::fromUtf8("label_21"));
+
+        gridLayout_6->addWidget(label_21, 1, 0, 1, 1);
+
+        label_22 = new QLabel(tab_2);
+        label_22->setObjectName(QString::fromUtf8("label_22"));
+
+        gridLayout_6->addWidget(label_22, 2, 0, 1, 1);
+
+        label_23 = new QLabel(tab_2);
+        label_23->setObjectName(QString::fromUtf8("label_23"));
+
+        gridLayout_6->addWidget(label_23, 3, 0, 1, 1);
+
+        lineEdit_abstol = new QLineEdit(tab_2);
+        lineEdit_abstol->setObjectName(QString::fromUtf8("lineEdit_abstol"));
+
+        gridLayout_6->addWidget(lineEdit_abstol, 1, 1, 1, 2);
+
+        lineEdit_speed = new QLineEdit(tab_2);
+        lineEdit_speed->setObjectName(QString::fromUtf8("lineEdit_speed"));
+
+        gridLayout_6->addWidget(lineEdit_speed, 2, 1, 1, 2);
+
+        lineEdit_iterMax = new QLineEdit(tab_2);
+        lineEdit_iterMax->setObjectName(QString::fromUtf8("lineEdit_iterMax"));
+
+        gridLayout_6->addWidget(lineEdit_iterMax, 3, 1, 1, 2);
+
+        comboBox_debugLevel = new QComboBox(tab_2);
+        comboBox_debugLevel->setObjectName(QString::fromUtf8("comboBox_debugLevel"));
+
+        gridLayout_6->addWidget(comboBox_debugLevel, 4, 1, 1, 2);
+
+        label_34 = new QLabel(tab_2);
+        label_34->setObjectName(QString::fromUtf8("label_34"));
+
+        gridLayout_6->addWidget(label_34, 4, 0, 1, 1);
+
+        checkBox_pause = new QCheckBox(tab_2);
+        checkBox_pause->setObjectName(QString::fromUtf8("checkBox_pause"));
+
+        gridLayout_6->addWidget(checkBox_pause, 7, 0, 1, 1);
+
+        lineEdit_rtol = new QLineEdit(tab_2);
+        lineEdit_rtol->setObjectName(QString::fromUtf8("lineEdit_rtol"));
+
+        gridLayout_6->addWidget(lineEdit_rtol, 0, 1, 1, 2);
+
+        checkBox_showSimplex = new QCheckBox(tab_2);
+        checkBox_showSimplex->setObjectName(QString::fromUtf8("checkBox_showSimplex"));
+
+        gridLayout_6->addWidget(checkBox_showSimplex, 7, 1, 1, 1);
+
+        checkBox_showConvergence = new QCheckBox(tab_2);
+        checkBox_showConvergence->setObjectName(QString::fromUtf8("checkBox_showConvergence"));
+        checkBox_showConvergence->setChecked(true);
+
+        gridLayout_6->addWidget(checkBox_showConvergence, 7, 2, 1, 1);
+
+        label_44 = new QLabel(tab_2);
+        label_44->setObjectName(QString::fromUtf8("label_44"));
+
+        gridLayout_6->addWidget(label_44, 6, 0, 1, 1);
+
+        lineEdit_random = new QLineEdit(tab_2);
+        lineEdit_random->setObjectName(QString::fromUtf8("lineEdit_random"));
+
+        gridLayout_6->addWidget(lineEdit_random, 6, 1, 1, 1);
+
+        tabWidget->addTab(tab_2, QString());
+        tab_6 = new QWidget();
+        tab_6->setObjectName(QString::fromUtf8("tab_6"));
+        gridLayout_8 = new QGridLayout(tab_6);
+        gridLayout_8->setObjectName(QString::fromUtf8("gridLayout_8"));
+        label_36 = new QLabel(tab_6);
+        label_36->setObjectName(QString::fromUtf8("label_36"));
+
+        gridLayout_8->addWidget(label_36, 0, 0, 1, 1);
+
+        lineEdit_joystick = new QLineEdit(tab_6);
+        lineEdit_joystick->setObjectName(QString::fromUtf8("lineEdit_joystick"));
+
+        gridLayout_8->addWidget(lineEdit_joystick, 0, 1, 1, 1);
+
+        toolButton = new QToolButton(tab_6);
+        toolButton->setObjectName(QString::fromUtf8("toolButton"));
+
+        gridLayout_8->addWidget(toolButton, 0, 2, 1, 1);
+
+        checkBox_joystickEnabled = new QCheckBox(tab_6);
+        checkBox_joystickEnabled->setObjectName(QString::fromUtf8("checkBox_joystickEnabled"));
+
+        gridLayout_8->addWidget(checkBox_joystickEnabled, 1, 0, 1, 2);
+
+        tabWidget->addTab(tab_6, QString());
+        tab_4 = new QWidget();
+        tab_4->setObjectName(QString::fromUtf8("tab_4"));
+        gridLayout_7 = new QGridLayout(tab_4);
+        gridLayout_7->setObjectName(QString::fromUtf8("gridLayout_7"));
+        label_15 = new QLabel(tab_4);
+        label_15->setObjectName(QString::fromUtf8("label_15"));
+
+        gridLayout_7->addWidget(label_15, 1, 0, 1, 1);
+
+        label_17 = new QLabel(tab_4);
+        label_17->setObjectName(QString::fromUtf8("label_17"));
+
+        gridLayout_7->addWidget(label_17, 6, 0, 1, 1);
+
+        label_19 = new QLabel(tab_4);
+        label_19->setObjectName(QString::fromUtf8("label_19"));
+
+        gridLayout_7->addWidget(label_19, 7, 0, 1, 1);
+
+        lineEdit_throttleGuess = new QLineEdit(tab_4);
+        lineEdit_throttleGuess->setObjectName(QString::fromUtf8("lineEdit_throttleGuess"));
+
+        gridLayout_7->addWidget(lineEdit_throttleGuess, 1, 1, 1, 1);
+
+        lineEdit_aileronGuess = new QLineEdit(tab_4);
+        lineEdit_aileronGuess->setObjectName(QString::fromUtf8("lineEdit_aileronGuess"));
+
+        gridLayout_7->addWidget(lineEdit_aileronGuess, 3, 1, 1, 1);
+
+        lineEdit_elevatorGuess = new QLineEdit(tab_4);
+        lineEdit_elevatorGuess->setObjectName(QString::fromUtf8("lineEdit_elevatorGuess"));
+
+        gridLayout_7->addWidget(lineEdit_elevatorGuess, 5, 1, 1, 1);
+
+        lineEdit_alphaGuess = new QLineEdit(tab_4);
+        lineEdit_alphaGuess->setObjectName(QString::fromUtf8("lineEdit_alphaGuess"));
+
+        gridLayout_7->addWidget(lineEdit_alphaGuess, 6, 1, 1, 1);
+
+        lineEdit_betaGuess = new QLineEdit(tab_4);
+        lineEdit_betaGuess->setObjectName(QString::fromUtf8("lineEdit_betaGuess"));
+
+        gridLayout_7->addWidget(lineEdit_betaGuess, 7, 1, 1, 1);
+
+        label_24 = new QLabel(tab_4);
+        label_24->setObjectName(QString::fromUtf8("label_24"));
+
+        gridLayout_7->addWidget(label_24, 1, 5, 1, 1);
+
+        label_25 = new QLabel(tab_4);
+        label_25->setObjectName(QString::fromUtf8("label_25"));
+
+        gridLayout_7->addWidget(label_25, 3, 5, 1, 1);
+
+        label_26 = new QLabel(tab_4);
+        label_26->setObjectName(QString::fromUtf8("label_26"));
+
+        gridLayout_7->addWidget(label_26, 5, 5, 1, 1);
+
+        label_27 = new QLabel(tab_4);
+        label_27->setObjectName(QString::fromUtf8("label_27"));
+
+        gridLayout_7->addWidget(label_27, 6, 5, 1, 1);
+
+        label_28 = new QLabel(tab_4);
+        label_28->setObjectName(QString::fromUtf8("label_28"));
+
+        gridLayout_7->addWidget(label_28, 7, 5, 1, 1);
+
+        lineEdit_throttleMin = new QLineEdit(tab_4);
+        lineEdit_throttleMin->setObjectName(QString::fromUtf8("lineEdit_throttleMin"));
+
+        gridLayout_7->addWidget(lineEdit_throttleMin, 1, 2, 1, 1);
+
+        lineEdit_aileronMin = new QLineEdit(tab_4);
+        lineEdit_aileronMin->setObjectName(QString::fromUtf8("lineEdit_aileronMin"));
+
+        gridLayout_7->addWidget(lineEdit_aileronMin, 3, 2, 1, 1);
+
+        lineEdit_elevatorMin = new QLineEdit(tab_4);
+        lineEdit_elevatorMin->setObjectName(QString::fromUtf8("lineEdit_elevatorMin"));
+
+        gridLayout_7->addWidget(lineEdit_elevatorMin, 5, 2, 1, 1);
+
+        lineEdit_alphaMin = new QLineEdit(tab_4);
+        lineEdit_alphaMin->setObjectName(QString::fromUtf8("lineEdit_alphaMin"));
+
+        gridLayout_7->addWidget(lineEdit_alphaMin, 6, 2, 1, 1);
+
+        lineEdit_betaMin = new QLineEdit(tab_4);
+        lineEdit_betaMin->setObjectName(QString::fromUtf8("lineEdit_betaMin"));
+
+        gridLayout_7->addWidget(lineEdit_betaMin, 7, 2, 1, 1);
+
+        label_29 = new QLabel(tab_4);
+        label_29->setObjectName(QString::fromUtf8("label_29"));
+
+        gridLayout_7->addWidget(label_29, 0, 1, 1, 1);
+
+        label_30 = new QLabel(tab_4);
+        label_30->setObjectName(QString::fromUtf8("label_30"));
+
+        gridLayout_7->addWidget(label_30, 0, 2, 1, 1);
+
+        lineEdit_throttleMax = new QLineEdit(tab_4);
+        lineEdit_throttleMax->setObjectName(QString::fromUtf8("lineEdit_throttleMax"));
+
+        gridLayout_7->addWidget(lineEdit_throttleMax, 1, 3, 1, 1);
+
+        lineEdit_aileronMax = new QLineEdit(tab_4);
+        lineEdit_aileronMax->setObjectName(QString::fromUtf8("lineEdit_aileronMax"));
+
+        gridLayout_7->addWidget(lineEdit_aileronMax, 3, 3, 1, 1);
+
+        lineEdit_elevatorMax = new QLineEdit(tab_4);
+        lineEdit_elevatorMax->setObjectName(QString::fromUtf8("lineEdit_elevatorMax"));
+
+        gridLayout_7->addWidget(lineEdit_elevatorMax, 5, 3, 1, 1);
+
+        lineEdit_alphaMax = new QLineEdit(tab_4);
+        lineEdit_alphaMax->setObjectName(QString::fromUtf8("lineEdit_alphaMax"));
+
+        gridLayout_7->addWidget(lineEdit_alphaMax, 6, 3, 1, 1);
+
+        lineEdit_betaMax = new QLineEdit(tab_4);
+        lineEdit_betaMax->setObjectName(QString::fromUtf8("lineEdit_betaMax"));
+
+        gridLayout_7->addWidget(lineEdit_betaMax, 7, 3, 1, 1);
+
+        label_31 = new QLabel(tab_4);
+        label_31->setObjectName(QString::fromUtf8("label_31"));
+
+        gridLayout_7->addWidget(label_31, 0, 3, 1, 1);
+
+        label_16 = new QLabel(tab_4);
+        label_16->setObjectName(QString::fromUtf8("label_16"));
+
+        gridLayout_7->addWidget(label_16, 5, 0, 1, 1);
+
+        label_18 = new QLabel(tab_4);
+        label_18->setObjectName(QString::fromUtf8("label_18"));
+
+        gridLayout_7->addWidget(label_18, 3, 0, 1, 1);
+
+        label_32 = new QLabel(tab_4);
+        label_32->setObjectName(QString::fromUtf8("label_32"));
+
+        gridLayout_7->addWidget(label_32, 4, 0, 1, 1);
+
+        lineEdit_rudderGuess = new QLineEdit(tab_4);
+        lineEdit_rudderGuess->setObjectName(QString::fromUtf8("lineEdit_rudderGuess"));
+
+        gridLayout_7->addWidget(lineEdit_rudderGuess, 4, 1, 1, 1);
+
+        lineEdit_rudderMin = new QLineEdit(tab_4);
+        lineEdit_rudderMin->setObjectName(QString::fromUtf8("lineEdit_rudderMin"));
+
+        gridLayout_7->addWidget(lineEdit_rudderMin, 4, 2, 1, 1);
+
+        lineEdit_rudderMax = new QLineEdit(tab_4);
+        lineEdit_rudderMax->setObjectName(QString::fromUtf8("lineEdit_rudderMax"));
+
+        gridLayout_7->addWidget(lineEdit_rudderMax, 4, 3, 1, 1);
+
+        label_33 = new QLabel(tab_4);
+        label_33->setObjectName(QString::fromUtf8("label_33"));
+
+        gridLayout_7->addWidget(label_33, 4, 5, 1, 1);
+
+        lineEdit_throttleInitialStepSize = new QLineEdit(tab_4);
+        lineEdit_throttleInitialStepSize->setObjectName(QString::fromUtf8("lineEdit_throttleInitialStepSize"));
+
+        gridLayout_7->addWidget(lineEdit_throttleInitialStepSize, 1, 4, 1, 1);
+
+        lineEdit_aileronInitialStepSize = new QLineEdit(tab_4);
+        lineEdit_aileronInitialStepSize->setObjectName(QString::fromUtf8("lineEdit_aileronInitialStepSize"));
+
+        gridLayout_7->addWidget(lineEdit_aileronInitialStepSize, 3, 4, 1, 1);
+
+        lineEdit_rudderInitialStepSize = new QLineEdit(tab_4);
+        lineEdit_rudderInitialStepSize->setObjectName(QString::fromUtf8("lineEdit_rudderInitialStepSize"));
+
+        gridLayout_7->addWidget(lineEdit_rudderInitialStepSize, 4, 4, 1, 1);
+
+        lineEdit_elevatorInitialStepSize = new QLineEdit(tab_4);
+        lineEdit_elevatorInitialStepSize->setObjectName(QString::fromUtf8("lineEdit_elevatorInitialStepSize"));
+
+        gridLayout_7->addWidget(lineEdit_elevatorInitialStepSize, 5, 4, 1, 1);
+
+        lineEdit_alphaInitialStepSize = new QLineEdit(tab_4);
+        lineEdit_alphaInitialStepSize->setObjectName(QString::fromUtf8("lineEdit_alphaInitialStepSize"));
+
+        gridLayout_7->addWidget(lineEdit_alphaInitialStepSize, 6, 4, 1, 1);
+
+        lineEdit_betaInitialStepSize = new QLineEdit(tab_4);
+        lineEdit_betaInitialStepSize->setObjectName(QString::fromUtf8("lineEdit_betaInitialStepSize"));
+
+        gridLayout_7->addWidget(lineEdit_betaInitialStepSize, 7, 4, 1, 1);
+
+        label_37 = new QLabel(tab_4);
+        label_37->setObjectName(QString::fromUtf8("label_37"));
+
+        gridLayout_7->addWidget(label_37, 0, 4, 1, 1);
+
+        tabWidget->addTab(tab_4, QString());
+        tab_5 = new QWidget();
+        tab_5->setObjectName(QString::fromUtf8("tab_5"));
+        gridLayout_3 = new QGridLayout(tab_5);
+        gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3"));
+        label_35 = new QLabel(tab_5);
+        label_35->setObjectName(QString::fromUtf8("label_35"));
+
+        gridLayout_3->addWidget(label_35, 0, 0, 1, 1);
+
+        lineEdit_linearizationFile = new QLineEdit(tab_5);
+        lineEdit_linearizationFile->setObjectName(QString::fromUtf8("lineEdit_linearizationFile"));
+
+        gridLayout_3->addWidget(lineEdit_linearizationFile, 0, 1, 1, 1);
+
+        tabWidget->addTab(tab_5, QString());
+
+        gridLayout_4->addWidget(tabWidget, 0, 0, 1, 1);
+
+        guidanceDock->setWidget(dockWidgetContents_6);
+        MainWindow->addDockWidget(static_cast<Qt::DockWidgetArea>(8), guidanceDock);
+
+        retranslateUi(MainWindow);
+        QObject::connect(actionQuit, SIGNAL(triggered()), MainWindow, SLOT(close()));
+
+        tabWidget->setCurrentIndex(5);
+
+
+        QMetaObject::connectSlotsByName(MainWindow);
+    } // setupUi
+
+    void retranslateUi(QMainWindow *MainWindow)
+    {
+        MainWindow->setWindowTitle(QApplication::translate("MainWindow", "mavsim Trim Program (for JSBSim models)", 0, QApplication::UnicodeUTF8));
+        actionQuit->setText(QApplication::translate("MainWindow", "Quit", 0, QApplication::UnicodeUTF8));
+        actionLoad_Map->setText(QApplication::translate("MainWindow", "Load Map", 0, QApplication::UnicodeUTF8));
+        pushButton_trim->setText(QApplication::translate("MainWindow", "Trim", 0, QApplication::UnicodeUTF8));
+        pushButton_simulate->setText(QApplication::translate("MainWindow", "Simulate", 0, QApplication::UnicodeUTF8));
+        pushButton_linearize->setText(QApplication::translate("MainWindow", "Linearize", 0, QApplication::UnicodeUTF8));
+        pushButton_stop->setText(QApplication::translate("MainWindow", "Stop", 0, QApplication::UnicodeUTF8));
+        guidanceDock->setWindowTitle(QApplication::translate("MainWindow", "Trim Algorithm", 0, QApplication::UnicodeUTF8));
+        label_2->setText(QApplication::translate("MainWindow", "Engine Path", 0, QApplication::UnicodeUTF8));
+        lineEdit_enginePath->setText(QString());
+        label_4->setText(QApplication::translate("MainWindow", "Systems Path", 0, QApplication::UnicodeUTF8));
+        label_3->setText(QApplication::translate("MainWindow", "Aircraft Path", 0, QApplication::UnicodeUTF8));
+        lineEdit_systemsPath->setText(QString());
+        toolButton_enginePath->setText(QApplication::translate("MainWindow", "...", 0, QApplication::UnicodeUTF8));
+        toolButton_systemsPath->setText(QApplication::translate("MainWindow", "...", 0, QApplication::UnicodeUTF8));
+        toolButton_aircraftPath->setText(QApplication::translate("MainWindow", "...", 0, QApplication::UnicodeUTF8));
+        label_9->setText(QApplication::translate("MainWindow", "Aircraft", 0, QApplication::UnicodeUTF8));
+        lineEdit_aircraft->setText(QString());
+        toolButton_aircraft->setText(QApplication::translate("MainWindow", "...", 0, QApplication::UnicodeUTF8));
+        label_5->setText(QApplication::translate("MainWindow", "Initialization Script", 0, QApplication::UnicodeUTF8));
+        lineEdit_initScript->setText(QString());
+        toolButton_initScript->setText(QApplication::translate("MainWindow", "...", 0, QApplication::UnicodeUTF8));
+        lineEdit_aircraftPath->setText(QString());
+        label_38->setText(QApplication::translate("MainWindow", "model sim rate", 0, QApplication::UnicodeUTF8));
+        lineEdit_modelSimRate->setText(QApplication::translate("MainWindow", "120", 0, QApplication::UnicodeUTF8));
+        label_39->setText(QApplication::translate("MainWindow", "Hz", 0, QApplication::UnicodeUTF8));
+        tabWidget->setTabText(tabWidget->indexOf(tab_3), QApplication::translate("MainWindow", "Aircraft", 0, QApplication::UnicodeUTF8));
+        label_10->setText(QApplication::translate("MainWindow", "mode", 0, QApplication::UnicodeUTF8));
+        comboBox_mode->clear();
+        comboBox_mode->insertItems(0, QStringList()
+         << QApplication::translate("MainWindow", "Steady Level Flight", 0, QApplication::UnicodeUTF8)
+         << QApplication::translate("MainWindow", "Coordinated Turn", 0, QApplication::UnicodeUTF8)
+         << QApplication::translate("MainWindow", "Push Over", 0, QApplication::UnicodeUTF8)
+         << QApplication::translate("MainWindow", "Pull Back", 0, QApplication::UnicodeUTF8)
+        );
+        label->setText(QApplication::translate("MainWindow", "velocity", 0, QApplication::UnicodeUTF8));
+        lineEdit_velocity->setText(QApplication::translate("MainWindow", "500", 0, QApplication::UnicodeUTF8));
+        label_11->setText(QApplication::translate("MainWindow", "ft/s", 0, QApplication::UnicodeUTF8));
+        label_6->setText(QApplication::translate("MainWindow", "roll rate", 0, QApplication::UnicodeUTF8));
+        lineEdit_rollRate->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        label_12->setText(QApplication::translate("MainWindow", "rad/s", 0, QApplication::UnicodeUTF8));
+        label_7->setText(QApplication::translate("MainWindow", "pitch rate", 0, QApplication::UnicodeUTF8));
+        lineEdit_pitchRate->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        label_13->setText(QApplication::translate("MainWindow", "rad/s", 0, QApplication::UnicodeUTF8));
+        label_8->setText(QApplication::translate("MainWindow", "yaw rate", 0, QApplication::UnicodeUTF8));
+        label_14->setText(QApplication::translate("MainWindow", "rad/s", 0, QApplication::UnicodeUTF8));
+        lineEdit_yawRate->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        checkBox_stabAxisRoll->setText(QApplication::translate("MainWindow", "stability axis roll", 0, QApplication::UnicodeUTF8));
+        label_40->setText(QApplication::translate("MainWindow", "altitude", 0, QApplication::UnicodeUTF8));
+        lineEdit_altitude->setText(QApplication::translate("MainWindow", "1000", 0, QApplication::UnicodeUTF8));
+        label_41->setText(QApplication::translate("MainWindow", "ft", 0, QApplication::UnicodeUTF8));
+        label_42->setText(QApplication::translate("MainWindow", "flight path angle", 0, QApplication::UnicodeUTF8));
+        lineEdit_gamma->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        checkBox_variablePropPitch->setText(QApplication::translate("MainWindow", "variable prop ptich", 0, QApplication::UnicodeUTF8));
+        label_43->setText(QApplication::translate("MainWindow", "deg", 0, QApplication::UnicodeUTF8));
+        tabWidget->setTabText(tabWidget->indexOf(tab), QApplication::translate("MainWindow", "Trim Conditions", 0, QApplication::UnicodeUTF8));
+        label_20->setText(QApplication::translate("MainWindow", "relative tolerance", 0, QApplication::UnicodeUTF8));
+        label_21->setText(QApplication::translate("MainWindow", "absolute tolerance", 0, QApplication::UnicodeUTF8));
+        label_22->setText(QApplication::translate("MainWindow", "convergence relative step size", 0, QApplication::UnicodeUTF8));
+        label_23->setText(QApplication::translate("MainWindow", "max iterations", 0, QApplication::UnicodeUTF8));
+        lineEdit_abstol->setText(QApplication::translate("MainWindow", "1e-2", 0, QApplication::UnicodeUTF8));
+        lineEdit_speed->setText(QApplication::translate("MainWindow", "1.1", 0, QApplication::UnicodeUTF8));
+        lineEdit_iterMax->setText(QApplication::translate("MainWindow", "2000", 0, QApplication::UnicodeUTF8));
+        comboBox_debugLevel->clear();
+        comboBox_debugLevel->insertItems(0, QStringList()
+         << QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8)
+         << QApplication::translate("MainWindow", "1", 0, QApplication::UnicodeUTF8)
+         << QApplication::translate("MainWindow", "2", 0, QApplication::UnicodeUTF8)
+        );
+        label_34->setText(QApplication::translate("MainWindow", "debug level", 0, QApplication::UnicodeUTF8));
+        checkBox_pause->setText(QApplication::translate("MainWindow", "pause ", 0, QApplication::UnicodeUTF8));
+        lineEdit_rtol->setText(QApplication::translate("MainWindow", "1e-4", 0, QApplication::UnicodeUTF8));
+        checkBox_showSimplex->setText(QApplication::translate("MainWindow", "show simplex", 0, QApplication::UnicodeUTF8));
+        checkBox_showConvergence->setText(QApplication::translate("MainWindow", "show convergence", 0, QApplication::UnicodeUTF8));
+        label_44->setText(QApplication::translate("MainWindow", "randomization factor", 0, QApplication::UnicodeUTF8));
+        lineEdit_random->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        tabWidget->setTabText(tabWidget->indexOf(tab_2), QApplication::translate("MainWindow", "Solver", 0, QApplication::UnicodeUTF8));
+        label_36->setText(QApplication::translate("MainWindow", "joystick device", 0, QApplication::UnicodeUTF8));
+        lineEdit_joystick->setText(QApplication::translate("MainWindow", "/dev/input/js0", 0, QApplication::UnicodeUTF8));
+        toolButton->setText(QApplication::translate("MainWindow", "...", 0, QApplication::UnicodeUTF8));
+        checkBox_joystickEnabled->setText(QApplication::translate("MainWindow", "joystick enabled", 0, QApplication::UnicodeUTF8));
+        tabWidget->setTabText(tabWidget->indexOf(tab_6), QApplication::translate("MainWindow", "Input", 0, QApplication::UnicodeUTF8));
+        label_15->setText(QApplication::translate("MainWindow", "Throttle", 0, QApplication::UnicodeUTF8));
+        label_17->setText(QApplication::translate("MainWindow", "Alpha", 0, QApplication::UnicodeUTF8));
+        label_19->setText(QApplication::translate("MainWindow", "Beta", 0, QApplication::UnicodeUTF8));
+        lineEdit_throttleGuess->setText(QApplication::translate("MainWindow", "50", 0, QApplication::UnicodeUTF8));
+        lineEdit_aileronGuess->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        lineEdit_elevatorGuess->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        lineEdit_alphaGuess->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        lineEdit_betaGuess->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        label_24->setText(QApplication::translate("MainWindow", "%", 0, QApplication::UnicodeUTF8));
+        label_25->setText(QApplication::translate("MainWindow", "%", 0, QApplication::UnicodeUTF8));
+        label_26->setText(QApplication::translate("MainWindow", "%", 0, QApplication::UnicodeUTF8));
+        label_27->setText(QApplication::translate("MainWindow", "deg", 0, QApplication::UnicodeUTF8));
+        label_28->setText(QApplication::translate("MainWindow", "deg", 0, QApplication::UnicodeUTF8));
+        lineEdit_throttleMin->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        lineEdit_aileronMin->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        lineEdit_elevatorMin->setText(QApplication::translate("MainWindow", "-100", 0, QApplication::UnicodeUTF8));
+        lineEdit_alphaMin->setText(QApplication::translate("MainWindow", "-10", 0, QApplication::UnicodeUTF8));
+        lineEdit_betaMin->setText(QApplication::translate("MainWindow", "-10", 0, QApplication::UnicodeUTF8));
+        label_29->setText(QApplication::translate("MainWindow", "Guess", 0, QApplication::UnicodeUTF8));
+        label_30->setText(QApplication::translate("MainWindow", "Lower Bound", 0, QApplication::UnicodeUTF8));
+        lineEdit_throttleMax->setText(QApplication::translate("MainWindow", "100", 0, QApplication::UnicodeUTF8));
+        lineEdit_aileronMax->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        lineEdit_elevatorMax->setText(QApplication::translate("MainWindow", "100", 0, QApplication::UnicodeUTF8));
+        lineEdit_alphaMax->setText(QApplication::translate("MainWindow", "20", 0, QApplication::UnicodeUTF8));
+        lineEdit_betaMax->setText(QApplication::translate("MainWindow", "5", 0, QApplication::UnicodeUTF8));
+        label_31->setText(QApplication::translate("MainWindow", "Upper Bound", 0, QApplication::UnicodeUTF8));
+        label_16->setText(QApplication::translate("MainWindow", "Elevator", 0, QApplication::UnicodeUTF8));
+        label_18->setText(QApplication::translate("MainWindow", "Aileron", 0, QApplication::UnicodeUTF8));
+        label_32->setText(QApplication::translate("MainWindow", "Rudder", 0, QApplication::UnicodeUTF8));
+        lineEdit_rudderGuess->setText(QApplication::translate("MainWindow", "0", 0, QApplication::UnicodeUTF8));
+        lineEdit_rudderMin->setText(QApplication::translate("MainWindow", "-100", 0, QApplication::UnicodeUTF8));
+        lineEdit_rudderMax->setText(QApplication::translate("MainWindow", "100", 0, QApplication::UnicodeUTF8));
+        label_33->setText(QApplication::translate("MainWindow", "%", 0, QApplication::UnicodeUTF8));
+        lineEdit_throttleInitialStepSize->setText(QApplication::translate("MainWindow", "20", 0, QApplication::UnicodeUTF8));
+        lineEdit_aileronInitialStepSize->setText(QApplication::translate("MainWindow", "10", 0, QApplication::UnicodeUTF8));
+        lineEdit_rudderInitialStepSize->setText(QApplication::translate("MainWindow", "10", 0, QApplication::UnicodeUTF8));
+        lineEdit_elevatorInitialStepSize->setText(QApplication::translate("MainWindow", "10", 0, QApplication::UnicodeUTF8));
+        lineEdit_alphaInitialStepSize->setText(QApplication::translate("MainWindow", "10", 0, QApplication::UnicodeUTF8));
+        lineEdit_betaInitialStepSize->setText(QApplication::translate("MainWindow", "5", 0, QApplication::UnicodeUTF8));
+        label_37->setText(QApplication::translate("MainWindow", "Initial Step Size", 0, QApplication::UnicodeUTF8));
+        tabWidget->setTabText(tabWidget->indexOf(tab_4), QApplication::translate("MainWindow", "Initial Guess", 0, QApplication::UnicodeUTF8));
+        label_35->setText(QApplication::translate("MainWindow", "Linearization File", 0, QApplication::UnicodeUTF8));
+        tabWidget->setTabText(tabWidget->indexOf(tab_5), QApplication::translate("MainWindow", "Output", 0, QApplication::UnicodeUTF8));
+    } // retranslateUi
+
+};
+
+namespace Ui {
+    class MainWindow: public Ui_MainWindow {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // MAINWINDOW_H
diff --git a/gui/Makefile.am b/gui/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..17a6511effe7c8d9c7774e3fff1e59e8bd952c45
--- /dev/null
+++ b/gui/Makefile.am
@@ -0,0 +1,16 @@
+include $(top_srcdir)/autotroll.mk
+
+# initiliaze to null
+bin_PROGRAMS = 
+BUILT_SOURCES =
+
+bin_PROGRAMS += trim
+trim_SOURCES = main.cpp MainWindow.cpp MainWindow.hpp MainWindow.ui MainWindow.ui.h \
+			   osgUtils.cpp osgUtils.hpp Viewer.cpp Viewer.hpp QOSGAdapterWidget.cpp \
+			   QOSGAdapterWidget.hpp \
+			   $(top_srcdir)/src/math/FGNelderMead.cpp
+trim_CXXFLAGS = $(QT_CXXFLAGS) $(AM_CXXFLAGS)
+trim_CPPFLAGS = $(QT_CPPFLAGS) $(AM_CPPFLAGS) -DUSE_QT4 -DDATADIR=\"$(top_srcdir)/data\" -I$(top_srcdir)/src
+trim_LDFLAGS  = $(QT_LDFLAGS) $(LDFLAGS)
+trim_LDADD    = $(QT_LIBS) $(LDADD)
+BUILT_SOURCES += MainWindow.moc.cpp MainWindow.ui.h
diff --git a/gui/QOSGAdapterWidget.cpp b/gui/QOSGAdapterWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..204997f16d7befc605b020a4cc11c96cc358f85b
--- /dev/null
+++ b/gui/QOSGAdapterWidget.cpp
@@ -0,0 +1,194 @@
+/* OpenSceneGraph adapter widget
+*
+*  Permission is hereby granted, free of charge, to any person obtaining a copy
+*  of this software and associated documentation files (the "Software"), to deal
+*  in the Software without restriction, including without limitation the rights
+*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*  copies of the Software, and to permit persons to whom the Software is
+*  furnished to do so, subject to the following conditions:
+*
+*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*  THE SOFTWARE.
+*/
+
+#include "QOSGAdapterWidget.hpp"
+
+QOSGAdapterWidget::QOSGAdapterWidget( QWidget * parent, const char * name, const QGLWidget * shareWidget, WindowFlags f):
+#if USE_QT4
+    QGLWidget(parent, shareWidget, f)
+#else
+    QGLWidget(parent, name, shareWidget, f)
+#endif
+{
+    _gw = new osgViewer::GraphicsWindowEmbedded(0,0,width(),height());
+#if USE_QT4
+    setFocusPolicy(Qt::ClickFocus);
+#else
+    setFocusPolicy(QWidget::ClickFocus);
+#endif
+}
+
+void QOSGAdapterWidget::resizeGL( int width, int height )
+{
+    _gw->getEventQueue()->windowResize(0, 0, width, height );
+    _gw->resized(0,0,width,height);
+}
+
+void QOSGAdapterWidget::keyPressEvent( QKeyEvent* event )
+{
+#if USE_QT4
+    _gw->getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) *(event->text().toAscii().data() ) );
+#else
+    _gw->getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) event->ascii() );
+#endif
+}
+
+void QOSGAdapterWidget::keyReleaseEvent( QKeyEvent* event )
+{
+#if USE_QT4
+    _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) *(event->text().toAscii().data() ) );
+#else
+    _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) event->ascii() );
+#endif
+}
+
+void QOSGAdapterWidget::mousePressEvent( QMouseEvent* event )
+{
+    int button = 0;
+    switch (event->button())
+    {
+    case(Qt::LeftButton):
+        button = 1;
+        break;
+    case(Qt::MidButton):
+        button = 2;
+        break;
+    case(Qt::RightButton):
+        button = 3;
+        break;
+    case(Qt::NoButton):
+        button = 0;
+        break;
+    default:
+        button = 0;
+        break;
+    }
+    _gw->getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
+}
+
+void QOSGAdapterWidget::mouseReleaseEvent( QMouseEvent* event )
+{
+    int button = 0;
+    switch (event->button())
+    {
+    case(Qt::LeftButton):
+        button = 1;
+        break;
+    case(Qt::MidButton):
+        button = 2;
+        break;
+    case(Qt::RightButton):
+        button = 3;
+        break;
+    case(Qt::NoButton):
+        button = 0;
+        break;
+    default:
+        button = 0;
+        break;
+    }
+    _gw->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
+}
+
+void QOSGAdapterWidget::mouseMoveEvent( QMouseEvent* event )
+{
+    _gw->getEventQueue()->mouseMotion(event->x(), event->y());
+}
+
+int mainQOSGAdapterWidget(QApplication& a, osg::ArgumentParser& arguments)
+{
+    // load the scene.
+    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
+    if (!loadedModel)
+    {
+        std::cout << arguments[0] <<": No data loaded." << std::endl;
+        return 1;
+    }
+
+    std::cout<<"Using QOSGAdapterWidget - QGLWidget subclassed to integrate with osgViewer using its embedded graphics window support."<<std::endl;
+
+    if (arguments.read("--CompositeViewer"))
+    {
+        CompositeViewerQT* viewerWindow = new CompositeViewerQT;
+
+        unsigned int width = viewerWindow->width();
+        unsigned int height = viewerWindow->height();
+
+        {
+            osgViewer::View* view1 = new osgViewer::View;
+            view1->getCamera()->setGraphicsContext(viewerWindow->getGraphicsWindow());
+            view1->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(width)/static_cast<double>(height/2), 1.0, 1000.0);
+            view1->getCamera()->setViewport(new osg::Viewport(0,0,width,height/2));
+            view1->setCameraManipulator(new osgGA::TrackballManipulator);
+            view1->setSceneData(loadedModel.get());
+
+            viewerWindow->addView(view1);
+        }
+
+        {
+            osgViewer::View* view2 = new osgViewer::View;
+            view2->getCamera()->setGraphicsContext(viewerWindow->getGraphicsWindow());
+            view2->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(width)/static_cast<double>(height/2), 1.0, 1000.0);
+            view2->getCamera()->setViewport(new osg::Viewport(0,height/2,width,height/2));
+            view2->setCameraManipulator(new osgGA::TrackballManipulator);
+            view2->setSceneData(loadedModel.get());
+
+            viewerWindow->addView(view2);
+        }
+
+        viewerWindow->show();
+#if USE_QT4
+    }
+    else if (arguments.read("--mdi"))
+    {
+        std::cout<<"Using ViewetQT MDI version"<<std::endl;
+        /*
+        Following problems are found here:
+        - miminize causes loaded model to disappear (some problem with Camera matrix? - clampProjectionMatrix is invalid)
+        */
+        ViewerQT* viewerWindow = new ViewerQT;
+        viewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
+        viewerWindow->setSceneData(loadedModel.get());
+
+        QMainWindow* mw = new QMainWindow();
+        QMdiArea* mdiArea = new QMdiArea(mw);
+        mw->setCentralWidget(mdiArea);
+
+        QMdiSubWindow *subWindow = mdiArea->addSubWindow(viewerWindow);
+        subWindow->showMaximized();
+        subWindow->setWindowTitle("New Window");
+        mw->show();
+#endif // USE_QT4
+    }
+    else
+    {
+        ViewerQT* viewerWindow = new ViewerQT;
+
+        viewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
+        viewerWindow->setSceneData(loadedModel.get());
+
+        viewerWindow->show();
+    }
+
+
+    a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) );
+
+    return a.exec();
+}
+
+/*EOF*/
diff --git a/gui/QOSGAdapterWidget.hpp b/gui/QOSGAdapterWidget.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..976361072b5cd6bb3a39f864b8453b6a32f6f640
--- /dev/null
+++ b/gui/QOSGAdapterWidget.hpp
@@ -0,0 +1,147 @@
+/* OpenSceneGraph example, osganimate.
+*
+*  Permission is hereby granted, free of charge, to any person obtaining a copy
+*  of this software and associated documentation files (the "Software"), to deal
+*  in the Software without restriction, including without limitation the rights
+*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*  copies of the Software, and to permit persons to whom the Software is
+*  furnished to do so, subject to the following conditions:
+*
+*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*  THE SOFTWARE.
+*/
+
+#ifndef QOSGAdapterWidget_H
+#define QOSGAdapterWidget_H
+
+#include <osgViewer/Viewer>
+#include <osgViewer/CompositeViewer>
+#include <osgViewer/ViewerEventHandlers>
+#include <osgGA/TrackballManipulator>
+#include <osgDB/ReadFile>
+#include <QMutex>
+//#include "config.h"
+
+#if USE_QT4
+
+#include <QtCore/QString>
+#include <QtCore/QTimer>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QApplication>
+#include <QtOpenGL/QGLWidget>
+#include <QtGui/QMainWindow>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QMdiArea>
+
+using Qt::WindowFlags;
+
+#else
+
+class QWidget;
+#include <qtimer.h>
+#include <qgl.h>
+#include <qapplication.h>
+
+#define WindowFlags WFlags
+
+#endif
+
+#include <iostream>
+
+class QOSGAdapterWidget : public QGLWidget
+{
+public:
+
+    QOSGAdapterWidget( QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WindowFlags f = 0 );
+
+    virtual ~QOSGAdapterWidget() {}
+
+    osgViewer::GraphicsWindow* getGraphicsWindow()
+    {
+        return _gw.get();
+    }
+    const osgViewer::GraphicsWindow* getGraphicsWindow() const
+    {
+        return _gw.get();
+    }
+
+protected:
+
+    void init();
+
+    virtual void resizeGL( int width, int height );
+    virtual void keyPressEvent( QKeyEvent* event );
+    virtual void keyReleaseEvent( QKeyEvent* event );
+    virtual void mousePressEvent( QMouseEvent* event );
+    virtual void mouseReleaseEvent( QMouseEvent* event );
+    virtual void mouseMoveEvent( QMouseEvent* event );
+
+    osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
+};
+
+class ViewerQT : public osgViewer::Viewer, public QOSGAdapterWidget
+{
+public:
+
+	QMutex mutex;
+
+    ViewerQT(QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WindowFlags f = 0):
+            QOSGAdapterWidget( parent, name, shareWidget, f )
+    {
+        getCamera()->setViewport(new osg::Viewport(0,0,width(),height()));
+        getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(width())/static_cast<double>(height()), 1.0f, 10000.0f);
+        getCamera()->setGraphicsContext(getGraphicsWindow());
+
+        setThreadingModel(osgViewer::Viewer::SingleThreaded);
+
+        connect(&_timer, SIGNAL(timeout()), this, SLOT(updateGL()));
+        _timer.start(100);
+    }
+
+    virtual void paintGL()
+    {
+		mutex.lock();
+        frame();
+		mutex.unlock();
+    }
+
+protected:
+
+    QTimer _timer;
+};
+
+class CompositeViewerQT : public osgViewer::CompositeViewer, public QOSGAdapterWidget
+{
+public:
+
+	QMutex mutex;
+
+    CompositeViewerQT(QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WindowFlags f = 0):
+            QOSGAdapterWidget( parent, name, shareWidget, f )
+    {
+        setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
+
+        connect(&_timer, SIGNAL(timeout()), this, SLOT(updateGL()));
+        _timer.start(100);
+    }
+
+    virtual void paintGL()
+    {
+		mutex.lock();
+        frame();
+		mutex.unlock();
+    }
+
+protected:
+
+    QTimer _timer;
+};
+
+#endif
+
+/*EOF*/
diff --git a/gui/Viewer.cpp b/gui/Viewer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d38641d9b5da8ffd3f889c833a86eb6accf2b7be
--- /dev/null
+++ b/gui/Viewer.cpp
@@ -0,0 +1,76 @@
+/*
+ * Viewer.cpp
+ * Copyright (C) James Goppert 2010 <jgoppert@users.sourceforge.net>
+ *
+ * Viewer.cpp is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Viewer.cpp is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Viewer.hpp"
+#include <boost/bind.hpp>
+#include <osgGA/TrackballManipulator>
+
+namespace mavsim
+{
+
+namespace visualization
+{
+
+Viewer::Viewer(int fps) :
+    myThread(), myMutex(), myFps(fps)
+{
+    using namespace osgViewer;
+    setThreadSafeReferenceCounting(true);
+    setThreadSafeRefUnref(true);
+    setCameraManipulator(new osgGA::TrackballManipulator);
+}
+
+Viewer::~Viewer()
+{
+    if (myThread) myThread->join();
+}
+
+int Viewer::run()
+{
+    realize();
+    myThread.reset(new boost::thread(boost::bind(&Viewer::loop,this)));
+    return 0;
+}
+
+void Viewer::loop()
+{
+    while (!done())
+    {
+        lock();
+        frame();
+        unlock();
+        usleep(1e6/myFps);
+    }
+}
+
+void Viewer::lock()
+{
+    myMutex.lock();
+}
+
+void Viewer::unlock()
+{
+    myMutex.unlock();
+}
+
+} // visualization
+
+} // mavsim
+
+
+// vim:ts=4:sw=4
diff --git a/gui/Viewer.hpp b/gui/Viewer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2cbc6154f378703dc1d30cfbdec053319c7b9917
--- /dev/null
+++ b/gui/Viewer.hpp
@@ -0,0 +1,72 @@
+/*
+ * Viewer.hpp
+ * Copyright (C) James Goppert 2010 <jgoppert@users.sourceforge.net>
+ *
+ * Viewer.hpp is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Viewer.hpp is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef mavsim_Viewer_HPP
+#define mavsim_Viewer_HPP
+
+#include <osgViewer/Viewer>
+#include <boost/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/scoped_ptr.hpp>
+
+namespace mavsim
+{
+
+namespace visualization
+{
+
+/**
+ * The purpose of this class is to create a viewer for simulation purposes.
+ */
+class Viewer : public osgViewer::Viewer
+{
+public:
+    /**
+     * Constructor
+     */
+    Viewer(int fps = 20);
+    virtual ~Viewer();
+    /**
+     * Override default run to be mutex lockable
+     */
+    int run();
+    /**
+     * Function to frame viewer
+     */
+    void loop();
+    /**
+     * Unlock the mutex and allow the viewer to frame
+     */
+    void unlock();
+    /**
+     * Lock the mutex and prevent viewer from framing
+     */
+    void lock();
+private:
+    boost::scoped_ptr<boost::thread> myThread; // viewer thread
+    boost::mutex myMutex; // mutex lock to protect data for multi-threading
+    int myFps; // Approxmiate frames per second, neglects framing time
+};
+
+} // visualization
+
+} // mavsim
+
+#endif
+
+// vim:ts=4:sw=4
diff --git a/gui/main.cc b/gui/main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0bb82d4b35c900e99b510842edc6f9f83a740275
--- /dev/null
+++ b/gui/main.cc
@@ -0,0 +1,16 @@
+/*
+** main.cc for autotroll-test in /tmp/autotroll/src
+**
+** Made by SIGOURE Benoit
+** Mail   <sigoure.benoit@lrde.epita.fr>
+**
+** Started on  Mon Oct 16 11:04:14 2006 SIGOURE Benoit
+** Last update Mon Oct 16 11:04:50 2006 SIGOURE Benoit
+*/
+
+int qt_main (int, char **);
+
+int main (int argc, char **argv)
+{
+  return qt_main (argc, argv);
+}
diff --git a/gui/main.cpp b/gui/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..61683ceafacda032e3995e04f7f6bbc5f9f8e52c
--- /dev/null
+++ b/gui/main.cpp
@@ -0,0 +1,14 @@
+#include <QApplication>
+#include <QSplashScreen>
+#include "MainWindow.hpp"
+#include <X11/Xlib.h>
+
+int main (int argc, char * argv[])
+{
+	XInitThreads();
+    QApplication app(argc,argv);
+	app.processEvents();
+    MainWindow w;
+	w.show();
+    return app.exec();
+}
diff --git a/gui/osgUtils.cpp b/gui/osgUtils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c75bea2282211d1f934fa2748506b7d2b8770715
--- /dev/null
+++ b/gui/osgUtils.cpp
@@ -0,0 +1,591 @@
+/*
+ * osgUtils.cpp
+ * Copyright (C) James Goppert 2010 <jgoppert@users.sourceforge.net>
+ *
+ * osgUtils.cpp is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * osgUtils.cpp is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "osgUtils.hpp"
+#include <osg/Group>
+#include <iostream>
+#include <osgText/Text>
+#include <osg/Geode>
+#include <osg/AutoTransform>
+#include <osg/ShapeDrawable>
+#include <osg/PositionAttitudeTransform>
+#include <osg/Material>
+#include <osg/Depth>
+#include <osg/PointSprite>
+#include <osg/Point>
+#include <osgDB/ReadFile>
+#include <stdexcept>
+//#include "config.h"
+
+namespace mavsim
+{
+
+namespace visualization
+{
+
+std::vector<osg::Node*> findNamedNodes(const std::string& searchName,
+                                       osg::Node* currNode)
+{
+    osg::Group* currGroup;
+    std::vector<osg::Node*> foundNodes;
+    osg::Node *foundNode;
+
+    // check to see if we have a valid (non-NULL) node.
+    // if we do have a null node, return NULL.
+    if ( !currNode)
+    {
+        return foundNodes;
+    }
+
+    // We have a valid node, check to see if this is the node we
+    // are looking for. If so, return the current node.
+    if (currNode->getName() == searchName)
+    {
+        foundNodes.push_back(currNode);
+    }
+
+    // We have a valid node, but not the one we are looking for.
+    // Check to see if it has children (non-leaf node). If the node
+    // has children, check each of the child nodes by recursive call.
+    // If one of the recursive calls returns a non-null value we have
+    // found the correct node, so return this node.
+    // If we check all of the children and have not found the node,
+    // return NULL
+    currGroup = currNode->asGroup(); // returns NULL if not a group.
+    if ( currGroup )
+    {
+        for (unsigned int i = 0 ; i < currGroup->getNumChildren(); i ++)
+        {
+            std::vector<osg::Node*> subNodes = findNamedNodes(searchName, currGroup->getChild(i));
+            if (subNodes.size())
+                for(int j=0; j<subNodes.size(); j++) foundNodes.push_back(subNodes[j]); // found a match!
+        }
+    }
+    return foundNodes;
+}
+
+
+NodeFinder::NodeFinder(const std::string & name) :
+    osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+    myName(name), myNode(NULL)
+{
+}
+
+void NodeFinder::apply(osg::Node& node)
+{
+    if (node.getName() == myName)
+        myNode = &node;
+    // traverse rest of graph
+    traverse(node);
+}
+
+osg::Node* NodeFinder::getNode()
+{
+    return myNode.get();
+}
+
+NodeFinder::~NodeFinder()
+{
+}
+
+void attachNode(const std::string & nodeName,
+                osg::Node * attachNode,
+                osg::Node * rootNode)
+{
+    NodeFinder nf(nodeName);
+    nf.apply(*rootNode);
+    osg::Node * node = nf.getNode();
+    if (node != NULL)
+    {
+        osg::Group * group = node->asGroup();
+        osg::Group * parent = group->getParent(0);
+        parent->removeChild(group);
+        parent->addChild(attachNode->asGroup());
+        attachNode->asGroup()->addChild(group);
+    }
+    else
+    {
+        std::cerr << "node: " << nodeName << " not found." << std::endl;
+    }
+}
+
+Label::Label(
+    const osg::Vec3& position,
+    const std::string& message,
+    float characterSize,
+    float minScale,
+    float maxScale)
+{
+	/*
+    osgText::Text* text = new osgText::Text;
+    text->setCharacterSize(characterSize);
+    text->setText(message);
+    text->setAlignment(osgText::Text::CENTER_CENTER);
+
+    osg::Geode* geode = new osg::Geode;
+    geode->addDrawable(text);
+    geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+
+    osg::AutoTransform* at = new osg::AutoTransform;
+    at->addChild(geode);
+
+    at->setAutoRotateMode(osg::AutoTransform::ROTATE_TO_SCREEN);
+    at->setAutoScaleToScreen(true);
+    at->setMinimumScale(minScale);
+    at->setMaximumScale(maxScale);
+    at->setPosition(position);
+    addChild(at);
+	*/
+}
+
+Frame::Frame(
+    float size,
+    const std::string & xLabel,
+    const std::string & yLabel,
+    const std::string & zLabel,
+    const osg::Vec4 & xColor,
+    const osg::Vec4 & yColor,
+    const osg::Vec4 & zColor)
+{
+    addChild(new Vector3(osg::Vec3(0,0,0),
+                         osg::Vec3(size,0,0),xLabel,xColor));
+    addChild(new Vector3(osg::Vec3(0,0,0),
+                         osg::Vec3(0,size,0),yLabel,yColor));
+    addChild(new Vector3(osg::Vec3(0,0,0),
+                         osg::Vec3(0,0,size),zLabel,zColor));
+}
+
+Actuator::Actuator(
+    const std::string & name,
+    const osg::Vec3 & center,
+    osg::Node * root) :
+    myPat(new osg::PositionAttitudeTransform),
+    myCenter(center)
+{
+    attachNode(name,myPat,root);
+    myPat->setPosition(center);
+    myPat->setPivotPoint(center);
+}
+
+void Actuator::setAttitude(osg::Quat quat)
+{
+    myPat->setAttitude(quat);
+}
+
+void Actuator::setPosition(double x, double y, double z)
+{
+    myPat->setPosition(osg::Vec3(x,y,z)+myCenter);
+}
+
+Vector3::Vector3(const osg::Vec3 & start,
+                 const osg::Vec3 & end,
+                 const std::string & name,
+                 const osg::Vec4 & color) :
+    myPat(new osg::PositionAttitudeTransform)
+{
+    osg::Geode * geode = new osg::Geode;
+    geode->addDrawable(new osg::ShapeDrawable(
+                           new osg::Cone(osg::Vec3(0,0,.9),.05,.1)));
+    geode->addDrawable(new osg::ShapeDrawable(
+                           new osg::Cylinder(osg::Vec3(0,0,.45),.01,.9)));
+    osg::Material * material = new osg::Material;
+    material->setDiffuse(osg::Material::FRONT,color);
+    geode->getOrCreateStateSet()->setAttribute(material, osg::StateAttribute::OVERRIDE );
+    myPat->addChild(new Label(osg::Vec3(0,0,1),name));
+    myPat->addChild(geode);
+    myPat->getOrCreateStateSet()->setMode(GL_NORMALIZE,
+                                          osg::StateAttribute::ON);
+    set(start,end);
+    addChild(myPat);
+}
+
+
+void Vector3::set(const osg::Vec3 & start,
+                  const osg::Vec3 & end)
+{
+    osg::Vec3 delta = end-start;
+    double length = delta.normalize();
+    osg::Vec3 zAxis(0,0,1);
+    myPat->setAttitude(osg::Quat(acos(zAxis*delta),zAxis^delta));
+    myPat->setPosition(start);
+    myPat->setPivotPoint(start);
+    myPat->setScale(osg::Vec3(1,1,1)*length);
+}
+
+Ellipsoid::Ellipsoid(osg::Vec3d radii, osg::Vec3d center, osg::Vec4 color, int vBands, int hBands) :
+    myRadii(radii),
+    myCenter(center),
+    myVBands(vBands),
+    myHBands(hBands),
+    myGeom(new osg::Geometry),
+    myVertices(new osg::Vec3Array),
+    myNormals(new osg::Vec3Array),
+    myPrimitive(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP,0))
+{
+    osg::Geode * geode = new osg::Geode;
+    osg::Vec4Array * colors = new osg::Vec4Array;
+
+    myGeom->setVertexArray(myVertices);
+
+    colors->push_back(color);
+    myGeom->setColorArray(colors);
+    myGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
+
+    myGeom->setNormalArray(myNormals);
+    myGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
+
+    myGeom->addPrimitiveSet(myPrimitive);
+    geode->addDrawable(myGeom);
+
+    addChild(geode);
+
+    // transparency
+    if (color[3] != 1)
+    {
+        // Enable blending, select transparent bin.
+        osg::StateSet * stateSet = geode->getOrCreateStateSet();
+        stateSet->setMode( GL_BLEND, osg::StateAttribute::ON );
+        stateSet->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
+
+        // Enable depth test so that an opaque polygon will occlude a transparent one behind it.
+        stateSet->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON );
+
+        // Conversely, disable writing to depth buffer so that
+        //a transparent polygon will allow polygons behind it to shine thru.
+        //OSG renders transparent polygons after opaque ones.
+        osg::Depth * depth  = new osg::Depth;
+        depth->setWriteMask( false );
+        stateSet->setAttributeAndModes( depth, osg::StateAttribute::ON );
+
+        // Disable lighting
+        stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
+    }
+
+    draw();
+}
+
+Ellipsoid::~Ellipsoid()
+{
+}
+
+void Ellipsoid::setParam(osg::Vec3d radii, osg::Vec3d center)
+{
+    myRadii = radii;
+    myCenter = center;
+    draw();
+}
+
+void Ellipsoid::addPoint(osg::Vec3 vert)
+{
+    osg::Vec3 norm = vert - myCenter;
+    norm.normalize();
+    myNormals->push_back(norm);
+    myVertices->push_back(vert);
+    myPrimitive->push_back(myVertices->size()-1);
+}
+
+void Ellipsoid::draw()
+{
+    myNormals->clear();
+    myVertices->clear();
+    myPrimitive->clear();
+
+    osg::Vec3 nadir = myCenter+osg::Vec3(0,0,myRadii.z());
+    osg::Vec3 zenith = myCenter+osg::Vec3(0,0,-myRadii.z());
+
+    double hStep = 2*M_PI/myHBands, vStep = M_PI/myVBands;
+    for (double theta=0; theta<M_PI; theta+=hStep)
+    {
+        for (double phi=0; phi<2*M_PI; phi+=vStep)
+        {
+            if (phi != 0 && phi!= M_PI)
+            {
+                addPoint(osg::Vec3(myRadii.x()*sin(phi)*cos(theta)+myCenter.x(),
+                                   myRadii.y()*sin(phi)*sin(theta)+myCenter.y(),
+                                   myRadii.z()*cos(phi)+myCenter.z()));
+                addPoint(osg::Vec3(myRadii.x()*sin(phi)*cos(theta+hStep)+myCenter.x(),
+                                   myRadii.y()*sin(phi)*sin(theta+hStep)+myCenter.y(),
+                                   myRadii.z()*cos(phi)+myCenter.z()));
+            }
+            else if (phi == 0)
+            {
+                addPoint(nadir);
+                addPoint(nadir);
+            }
+            else if (phi == M_PI)
+            {
+                addPoint(zenith);
+                addPoint(zenith);
+            }
+            else std::cout<<"Error: Ellipsoid point not added"<<std::endl;
+        }
+    }
+    addPoint(nadir); //add last point of sphere
+    myGeom->dirtyDisplayList(); // force redraw
+}
+
+PointCloud::PointCloud(int pointSize) :
+    myPoints(new osg::Vec3Array),
+    myColors(new osg::Vec4Array),
+    myGeom(new osg::Geometry),
+    myDrawArrays(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, myPoints->size()))
+{
+    osg::Geode * geode = new osg::Geode;
+    addChild(geode);
+    geode->setStateSet(makeStateSet(pointSize));
+    geode->addDrawable(myGeom);
+    myGeom->setVertexArray(myPoints);
+    myGeom->setColorArray(myColors);
+    myGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
+    myGeom->addPrimitiveSet(myDrawArrays);
+}
+
+void PointCloud::addPoint(osg::Vec3 point, osg::Vec4 color)
+{
+    myPoints->push_back(point);
+    myColors->push_back(color);
+    updateSize();
+}
+
+void PointCloud::clear()
+{
+    myPoints->clear();
+    myColors->clear();
+    updateSize();
+}
+
+void PointCloud::updateSize()
+{
+    myDrawArrays->setCount(myPoints->size());
+    myGeom->dirtyDisplayList();
+}
+
+osg::StateSet* PointCloud::makeStateSet(float size)
+{
+    osg::StateSet *set = new osg::StateSet();
+
+    /// Setup the point sprites
+    osg::PointSprite *sprite = new osg::PointSprite();
+    set->setTextureAttributeAndModes(0, sprite, osg::StateAttribute::ON);
+
+    /// Give some size to the points to be able to see the sprite
+    osg::Point *point = new osg::Point();
+    point->setSize(size);
+    set->setAttribute(point);
+
+    /// Disable depth test to avoid sort problems and Lighting
+    set->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+    set->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+
+    return set;
+}
+
+Jet::Jet() :
+    modelPat(), model(), myLeftAileron(), myRightAileron(),
+    myLeftElevator(), myRightElevator(), myRudder()
+{
+ 	std::string modelFile("DATADIR/models/jet.ac");
+    model = osgDB::readNodeFile(modelFile);
+	if (!model)
+	{
+		throw(std::runtime_error("can't find model: " + modelFile));
+		return;
+	}
+	modelPat = new PositionAttitudeTransform;
+	modelPat->setAttitude(osg::Quat(-M_PI/2,osg::Vec3(1,0,0)));
+	modelPat->addChild(model);
+    myLeftAileron.reset(new Actuator("leftAileron",osg::Vec3(-1.077,-0.319,2.652),model));
+    myRightAileron.reset(new Actuator("rightAileron",osg::Vec3(-1.075,-0.319,-2.652),model));
+    myLeftElevator.reset(new Actuator("leftElevator",osg::Vec3(-5.806,0.320,1.511),model));
+    myRightElevator.reset(new Actuator("rightElevator",osg::Vec3(-5.806,0.320,-1.511),model));
+    myRudder.reset(new Actuator("rudder",osg::Vec3(-6.485,2.114,0.000),model));
+    myThrustPlume.reset(new Actuator("thrustPlume",osg::Vec3(0,0,0),model));
+    addChild(modelPat);
+}
+
+void Jet::setEuler(double roll, double pitch, double yaw)
+{
+    setAttitude(osg::Quat(
+                    roll,osg::Vec3(1,0,0),
+                    pitch,osg::Vec3(0,1,0),
+                    yaw,osg::Vec3(0,0,1)));
+}
+
+void Jet::setPositionScalars(double x, double y, double z)
+{
+    setPosition(osg::Vec3(x,y,z));
+}
+
+void Jet::setU(double throttle, double aileron, double elevator, double rudder)
+{
+    myLeftAileron->setAttitude(osg::Quat(aileron,osg::Vec3(0,0,1)));
+    myRightAileron->setAttitude(osg::Quat(-aileron,osg::Vec3(0,0,1)));
+    myLeftElevator->setAttitude(osg::Quat(elevator,osg::Vec3(0,0,1)));
+    myRightElevator->setAttitude(osg::Quat(elevator,osg::Vec3(0,0,1)));
+    myRudder->setAttitude(osg::Quat(rudder,osg::Vec3(0,1,0)));
+	myThrustPlume->setPosition(3-3*throttle,0,0);
+}
+
+Plane::Plane() :
+    model(), myLeftAileron(), myRightAileron(),
+    myLeftElevator(), myRightElevator(), myRudder(), propAngle()
+{
+ 	std::string modelFile("DATADIR/models/plane.ac");
+    model = osgDB::readNodeFile(modelFile);
+	if (!model)
+	{
+		throw(std::runtime_error("can't find model: " + modelFile));
+		return;
+	}
+	modelPat = new PositionAttitudeTransform;
+	modelPat->setAttitude(osg::Quat(-M_PI/2,osg::Vec3(1,0,0)));
+	modelPat->addChild(model);
+    myLeftAileron.reset(new Actuator("leftAileron",osg::Vec3(-0.063,-0.559,3.514),model));
+    myRightAileron.reset(new Actuator("rightAileron",osg::Vec3(-0.063,-0.559,-3.514),model));
+    myLeftElevator.reset(new Actuator("leftElevator",osg::Vec3(-5.651,-0.019,-0.115),model));
+    myRightElevator.reset(new Actuator("rightElevator",osg::Vec3(-5.651,0.019,-0.115),model));
+    myRudder.reset(new Actuator("rudder",osg::Vec3(-5.638,0.234,0.000),model));
+    myPropeller.reset(new Actuator("propeller",osg::Vec3(3.874,-0.353,0.003),model));
+    addChild(modelPat);
+}
+
+void Plane::setEuler(double roll, double pitch, double yaw)
+{
+    setAttitude(osg::Quat(
+                    roll,osg::Vec3(1,0,0),
+                    pitch,osg::Vec3(0,1,0),
+                    yaw,osg::Vec3(0,0,1)));
+}
+
+void Plane::setPositionScalars(double x, double y, double z)
+{
+    setPosition(osg::Vec3(x,y,z));
+}
+
+void Plane::setU(double throttle, double aileron, double elevator, double rudder)
+{
+	myLeftAileron->setAttitude(osg::Quat(aileron,osg::Vec3(0,0,1)));
+	myRightAileron->setAttitude(osg::Quat(-aileron,osg::Vec3(0,0,1)));
+	myLeftElevator->setAttitude(osg::Quat(elevator,osg::Vec3(0,0,1)));
+	myRightElevator->setAttitude(osg::Quat(elevator,osg::Vec3(0,0,1)));
+	myRudder->setAttitude(osg::Quat(rudder,osg::Vec3(0,1,0)));
+	myPropeller->setAttitude(osg::Quat(propAngle+=5*throttle,osg::Vec3(1,0,0)));
+}
+
+Car::Car() :
+    model(), myWheelLF(), myWheelLB(),
+    myWheelRF(), myWheelRB(),
+	myTireAngleLF(), myTireAngleLB(),
+	myTireAngleRF(), myTireAngleRB()
+{
+	std::string modelFile("DATADIR/models/rcTruck.ac");
+	std::cout << "model file: " << modelFile << std::endl;
+    model = osgDB::readNodeFile(modelFile);
+	if (!model)
+	{
+		throw(std::runtime_error("can't find model: " + modelFile));
+		return;
+	}
+	modelPat = new PositionAttitudeTransform;
+	modelPat->setAttitude(osg::Quat(-M_PI/2,osg::Vec3(1,0,0)));
+	modelPat->addChild(model);
+    myWheelLF.reset(new Actuator("wheelLF",osg::Vec3(0.304,-0.087,-0.260),model));
+    myWheelRF.reset(new Actuator("wheelRF",osg::Vec3(0.304,-0.087,0.260),model));
+    myWheelLB.reset(new Actuator("wheelLB",osg::Vec3(-0.304,-0.087,-0.260),model));
+    myWheelRB.reset(new Actuator("wheelRB",osg::Vec3(-0.304,-0.087,0.260),model));
+    addChild(modelPat);
+}
+
+void Car::setEuler(double roll, double pitch, double yaw)
+{
+    setAttitude(osg::Quat(
+                    roll,osg::Vec3(1,0,0),
+                    pitch,osg::Vec3(0,1,0),
+                    yaw,osg::Vec3(0,0,1)));
+}
+
+void Car::setPositionScalars(double x, double y, double z)
+{
+    setPosition(osg::Vec3(x,y,z));
+}
+
+void Car::setU(double throttle, double steering, double velocity)
+{
+	myWheelLF->setAttitude(osg::Quat(
+					myTireAngleLF-=0.5*throttle,osg::Vec3(0,0,1),
+                    0,osg::Vec3(1,0,0),
+                    steering,osg::Vec3(0,-1,0)));
+	myWheelLB->setAttitude(osg::Quat(myTireAngleLB-=0.5*throttle,osg::Vec3(0,0,1)));
+	myWheelRF->setAttitude(osg::Quat(
+					myTireAngleRF-=0.5*throttle,osg::Vec3(0,0,1),
+                    0,osg::Vec3(1,0,0),
+                    steering,osg::Vec3(0,-1,0)));
+	myWheelRB->setAttitude(osg::Quat(myTireAngleRB-=0.5*throttle,osg::Vec3(0,0,1)));
+}
+
+Quad::Quad() :
+    model(), myPropF(), myPropB(),myPropL(), myPropR(),
+	myPropAngleF(), myPropAngleB(), myPropAngleL(), myPropAngleR()
+{
+	std::string modelFile("DATADIR/models/arducopter.ac");
+	std::cout << "model file: " << modelFile << std::endl;
+    model = osgDB::readNodeFile(modelFile);
+	if (!model)
+	{
+		throw(std::runtime_error("can't find model: " + modelFile));
+		return;
+	}
+	modelPat = new PositionAttitudeTransform;
+	modelPat->setAttitude(osg::Quat(-M_PI/2,osg::Vec3(1,0,0)));
+	modelPat->addChild(model);
+    myPropF.reset(new Actuator("propellerF",osg::Vec3(0.288,0.046,0),modelPat));
+    myPropB.reset(new Actuator("propellerB",osg::Vec3(-0.288,0.046,0),modelPat));
+    myPropL.reset(new Actuator("propellerL",osg::Vec3(0,0.046,-0.288),modelPat));
+    myPropR.reset(new Actuator("propellerR",osg::Vec3(0,0.046,0.288),modelPat));
+    addChild(modelPat);
+}
+
+void Quad::setEuler(double roll, double pitch, double yaw)
+{
+    setAttitude(osg::Quat(
+                    roll,osg::Vec3(1,0,0),
+                    pitch,osg::Vec3(0,1,0),
+                    yaw,osg::Vec3(0,0,1)));
+}
+
+void Quad::setPositionScalars(double x, double y, double z)
+{
+    setPosition(osg::Vec3(x,y,z));
+}
+
+void Quad::setU(double throttleF, double throttleB, double throttleL, double throttleR)
+{
+	myPropF->setAttitude(osg::Quat(myPropAngleF-=-0.5*throttleF,osg::Vec3(0,1,0)));
+	myPropB->setAttitude(osg::Quat(myPropAngleB-=-0.5*throttleB,osg::Vec3(0,1,0)));
+	myPropL->setAttitude(osg::Quat(myPropAngleL-=0.5*throttleL,osg::Vec3(0,1,0)));
+	myPropR->setAttitude(osg::Quat(myPropAngleR-=0.5*throttleR,osg::Vec3(0,1,0)));
+}
+
+
+
+} // visualization
+
+} // mavsim
+
+
+// vim:ts=4:sw=4
diff --git a/gui/osgUtils.hpp b/gui/osgUtils.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..56c8f6777eef015980564290feaa0cb89e5037f8
--- /dev/null
+++ b/gui/osgUtils.hpp
@@ -0,0 +1,224 @@
+/*
+ * osgUtils.hpp
+ * Copyright (C) James Goppert 2010 <jgoppert@users.sourceforge.net>
+ *
+ * osgUtils.hpp is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * osgUtils.hpp is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef mavsim_osgUtils_HPP
+#define mavsim_osgUtils_HPP
+
+#include <osg/NodeVisitor>
+#include <osg/PositionAttitudeTransform>
+#include <osg/Geometry>
+#include <boost/scoped_ptr.hpp>
+
+#include <float.h>
+
+namespace mavsim
+{
+
+namespace visualization
+{
+
+static const osg::Vec4d white(1,1,1,1), red(1,0,0,1), green(0,1,0,1), blue(0,0,1,1), pink(1,0,1,1);
+
+std::vector<osg::Node*> findNamedNodes(const std::string& searchName, 
+									  osg::Node* currNode);
+
+class NodeFinder : public osg::NodeVisitor
+{
+public:
+    NodeFinder(const std::string & name);
+    // This method gets called for every node in the scene
+    // graph. It checks each node to see if its name matches
+    // the target. If so, it saves the node's address.
+    virtual void apply(osg::Node& node);
+    osg::Node* getNode();
+    virtual ~NodeFinder();
+protected:
+    std::string myName;
+    osg::ref_ptr<osg::Node> myNode;
+};
+
+void attachNode(const std::string & nodeName,
+                osg::Node * attachNode,
+                osg::Node * rootNode);
+
+class Label : public osg::Group
+{
+public:
+    Label(
+        const osg::Vec3& position,
+        const std::string& message,
+        float characterSize=40,
+        float minScale=0,
+        float maxScale=FLT_MAX);
+};
+
+class Frame : public osg::PositionAttitudeTransform
+{
+public:
+    Frame(
+        float size=10,
+        const std::string & xLabel="x",
+        const std::string & yLabel="y",
+        const std::string & zLabel="z",
+        const osg::Vec4 & xColor = osg::Vec4(1,0,0,1),
+        const osg::Vec4 & yColor = osg::Vec4(0,1,0,1),
+        const osg::Vec4 & zColor = osg::Vec4(0,0,1,1));
+};
+
+class Actuator
+{
+public:
+    Actuator(
+        const std::string & name,
+        const osg::Vec3 & center,
+        osg::Node * root);
+    void setAttitude(osg::Quat quat);
+    void setPosition(double x, double y, double z);
+private:
+    osg::PositionAttitudeTransform * myPat;
+    osg::Vec3 myCenter;
+};
+
+class Vector3 : public osg::Group
+{
+public:
+    Vector3(const osg::Vec3 & start,
+            const osg::Vec3 & end,
+            const std::string & name="",
+            const osg::Vec4 & color=osg::Vec4(1,0,0,1));
+    void set(const osg::Vec3 & start,
+             const osg::Vec3 & end);
+private:
+    osg::PositionAttitudeTransform * myPat;
+};
+
+class Ellipsoid : public osg::PositionAttitudeTransform
+{
+public:
+    Ellipsoid(osg::Vec3d radii, osg::Vec3d center, osg::Vec4 color=osg::Vec4(1,0,0,1),
+              int vBands = 10, int hBands = 10);
+    void draw();
+    virtual ~Ellipsoid();
+    void setParam(osg::Vec3d radii, osg::Vec3d center);
+    void addPoint(osg::Vec3 vec);
+
+private:
+    osg::Vec3d myRadii, myCenter;
+    int myVBands, myHBands;
+    osg::ref_ptr<osg::Geometry> myGeom;
+    osg::ref_ptr<osg::Vec3Array> myVertices;
+    osg::ref_ptr<osg::Vec3Array> myNormals;
+    osg::ref_ptr<osg::DrawElementsUInt> myPrimitive;
+};
+
+class PointCloud : public osg::PositionAttitudeTransform
+{
+public:
+    PointCloud(int pointSize);
+    void addPoint(osg::Vec3 point, osg::Vec4 color=osg::Vec4(1,1,1,0));
+    void clear();
+private:
+    void updateSize();
+    osg::ref_ptr<osg::Vec3Array> myPoints;
+    osg::ref_ptr<osg::Vec4Array> myColors;
+    osg::ref_ptr<osg::Geometry> myGeom;
+    osg::ref_ptr<osg::DrawArrays> myDrawArrays;
+    osg::StateSet* makeStateSet(float size);
+};
+
+class Jet : public osg::PositionAttitudeTransform
+{
+public:
+    Jet();
+    void setEuler(double roll, double pitch, double yaw);
+    void setPositionScalars(double x, double y, double z);
+    void setU(double throttle, double aileron, double elevator, double rudder);
+private:
+    osg::ref_ptr<osg::Node> model;
+	osg::ref_ptr<osg::PositionAttitudeTransform> modelPat;
+    boost::scoped_ptr<Actuator> myLeftAileron;
+    boost::scoped_ptr<Actuator> myRightAileron;
+    boost::scoped_ptr<Actuator> myLeftElevator;
+    boost::scoped_ptr<Actuator> myRightElevator;
+    boost::scoped_ptr<Actuator> myRudder;
+    boost::scoped_ptr<Actuator> myThrustPlume;
+};
+
+class Plane : public osg::PositionAttitudeTransform
+{
+public:
+    Plane();
+    void setEuler(double roll, double pitch, double yaw);
+    void setPositionScalars(double x, double y, double z);
+    void setU(double throttle, double aileron, double elevator, double rudder);
+private:
+	double propAngle;
+    osg::ref_ptr<osg::Node> model;
+	osg::ref_ptr<osg::PositionAttitudeTransform> modelPat;
+    boost::scoped_ptr<Actuator> myLeftAileron;
+    boost::scoped_ptr<Actuator> myRightAileron;
+    boost::scoped_ptr<Actuator> myLeftElevator;
+    boost::scoped_ptr<Actuator> myRightElevator;
+    boost::scoped_ptr<Actuator> myRudder;
+    boost::scoped_ptr<Actuator> myPropeller;
+};
+
+class Car : public osg::PositionAttitudeTransform
+{
+public:
+    Car();
+    void setEuler(double roll, double pitch, double yaw);
+    void setPositionScalars(double x, double y, double z);
+    void setU(double throttle, double steering, double velocity);
+private:
+    osg::ref_ptr<osg::Node> model;
+	osg::ref_ptr<osg::PositionAttitudeTransform> modelPat;
+	double myTireAngleLF, myTireAngleLB, myTireAngleRF, myTireAngleRB;
+    boost::scoped_ptr<Actuator> myWheelLF;
+    boost::scoped_ptr<Actuator> myWheelLB;
+	boost::scoped_ptr<Actuator> myWheelRF;
+    boost::scoped_ptr<Actuator> myWheelRB;
+};
+
+class Quad : public osg::PositionAttitudeTransform
+{
+public:
+    Quad();
+    void setEuler(double roll, double pitch, double yaw);
+    void setPositionScalars(double x, double y, double z);
+    void setU(double throttleF, double throttleB, double throttleL, double throttleR);
+private:
+	double myPropAngleF, myPropAngleB, myPropAngleL, myPropAngleR;
+    osg::ref_ptr<osg::Node> model;
+	osg::ref_ptr<osg::PositionAttitudeTransform> modelPat;
+    boost::scoped_ptr<Actuator> myPropF;
+    boost::scoped_ptr<Actuator> myPropB;
+	boost::scoped_ptr<Actuator> myPropL;
+    boost::scoped_ptr<Actuator> myPropR;
+};
+
+
+
+
+} // visualization
+
+} // mavsim
+
+#endif
+
+// vim:ts=4:sw=4
diff --git a/gui/qt_main.cpp b/gui/qt_main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5fc4ddcefeb153ab01be299a7101e55ea72fbd66
--- /dev/null
+++ b/gui/qt_main.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2005-2006 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QFont>
+#include <QGridLayout>
+#include <QPushButton>
+#include <QWidget>
+
+#include "lcdrange.h"
+
+class MyWidget : public QWidget
+{
+public:
+    MyWidget(QWidget *parent = 0);
+};
+
+MyWidget::MyWidget(QWidget *parent)
+    : QWidget(parent)
+{
+    QPushButton *quit = new QPushButton(tr("Quit"));
+    quit->setFont(QFont("Times", 18, QFont::Bold));
+
+    connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
+
+    QGridLayout *grid = new QGridLayout;
+    LCDRange *previousRange = 0;
+
+    for (int row = 0; row < 3; ++row) {
+        for (int column = 0; column < 3; ++column) {
+            LCDRange *lcdRange = new LCDRange;
+            grid->addWidget(lcdRange, row, column);
+            if (previousRange)
+                connect(lcdRange, SIGNAL(valueChanged(int)),
+                        previousRange, SLOT(setValue(int)));
+            previousRange = lcdRange;
+        }
+    }
+    QVBoxLayout *layout = new QVBoxLayout;
+    layout->addWidget(quit);
+    layout->addLayout(grid);
+    setLayout(layout);
+}
+
+int qt_main(int argc, char *argv[])
+{
+    QApplication app(argc, argv);
+    MyWidget widget;
+    widget.show();
+    return app.exec();
+}
diff --git a/gui/textures.qrc b/gui/textures.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..dfde5e1236fedbf03f28e3dff4beb8ff2828783a
--- /dev/null
+++ b/gui/textures.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>data/some.txt</file>
+</qresource>
+</RCC>