openrocket/doc/techdoc/chapter-software.tex

476 lines
20 KiB
TeX
Raw Normal View History

2010-07-17 22:52:23 +00:00
\chapter{The OpenRocket simulation software}
\label{chap-software}
The flight simulation described in the previous chapters was
implemented in the {\it OpenRocket} simulation
software~\cite{openrocket}. The software was written entirely in Java
for maximum portability between different operating systems. A
significant amount of effort was put into making the graphical user
interface (UI) robust, intuitive and easy to use. As of the first
public release the source code contained over 300 classes and over
47\s000 lines of code (including comments and blank lines).
The software was released under the copyleft GNU General Public
License (GPL)~\cite{gnu-gpl}, allowing everybody access to the source code
and permitting use and modification for any purposes. The only major
restriction placed is that if a modified version is distributed, the
source code for the modifications must also be available under the GNU
GPL. This ensures that the program stays free and Open Source; a
company cannot simply take the code, enhance it and start selling it
as their own without contributing anything back to the community.
In this section the basic architectural designs are discussed and the
main features of the UI are explained.
\section{Architectural design}
The software has been split into various components within their own
Java packages. This enables use of the components without needing the
other components. For example, all of the UI code is within the
\code{gui} package, and the simulation system can be used
independently of it.
The rocket structure is composed of components, each with their
own class defined within the package \code{rocketcomponent}. This
provides the base for defining a rocket. The components are described
in more detail in Section~\ref{sec-rocket-components}. The simulation
code is separated from the aerodynamic calculation code in the
\code{simulation} and \code{aerodynamics} packages, respectively;
these are discussed in Section~\ref{sec-simulator-calculator}.
The package naming convention recommended in the Java Language
Specification is followed~\cite{java-packages}. Therefore all package
names discussed herein are relative to the package
\url{net.sf.openrocket}. For example, the rocket components are
defined in the package \url{net.sf.openrocket.rocketcomponent}.
\subsection{Rocket components}
\label{sec-rocket-components}
The structure of the rocket is split up into {\it components}, for
example nose cones, body tubes and components within the rocket body.
Each component type is defined as a subclass of the abstract
\code{RocketComponent} class. Each component can contain zero or more
components attached to it, which creates a tree structure containing
the entire rocket design. The base component of every design is a
\code{Rocket} object, which holds one or more \code{Stage} objects.
These represent the stages of the rocket and hold all of the physical
components.
Inheritance has been highly used in the class hierarchy of the
components in order to combine common features of various components.
There are also some abstract classes, such as \code{BodyComponent},
whose sole purpose currently is to allow future extensions. The
complete component class hierarchy is presented as a UML diagram in
Figure~\ref{fig-rocketcomponent-uml}, and a more detailed description
of each class is presented in Table~\ref{table-rocketcomponents}.
\begin{sidewaysfigure}
\centering
\hspace{-1cm}
\epsfig{file=figures/software/rocketcomponents,width=20cm}
\caption{A UML diagram of the rocket component classes. Abstract
classes are shown in italics.}
\label{fig-rocketcomponent-uml}
\end{sidewaysfigure}
\begin{table}
\caption{Descriptions of the rocket component classes and their
functionality. Abstract classes are shown in italics.}
\label{table-rocketcomponents}
\sloppy\footnotesize
\vspace{\baselineskip}
\hspace{-5mm}\begin{tabular}{lp{80mm}}
Component class & Description \\
\hline
\code{\textit{RocketComponent}}: &
The base class of all components,
including common features such as child component handling. \\
\hspace{3mm}\code{Rocket}: &
The base component of a
rocket design, provides change event notifications. \\
\hspace{3mm}\code{\textit{ComponentAssembly}}: &
A base component for an assembly of external components. This could
in the future be extended to allow multiple rocket bodies next to
each other. \\
\hspace{6mm}\code{Stage}: &
A separable stage of the rocket. \\
\hspace{3mm}\code{\textit{ExternalComponent}}: &
An external component that has an effect on the aerodynamics of the
rocket. \\
\hspace{6mm}\code{\textit{BodyComponent}}: &
A portion of the main rocket body, defined in cylindrical coordinates
by $r = f(x, \theta)$. \\
\hspace{9mm}\code{\textit{SymmetricComponent}}: &
An axisymmetrical body component. \\
\hspace{12mm}\code{Transition}: &
A symmetrical transition (shoulder or boattail). \\
\hspace{15mm}\code{NoseCone}: &
A transition with the initial radius zero. \\
\hspace{12mm}\code{BodyTube}: &
A cylindrical body tube. Can be used as a motor mount. \\
\hspace{6mm}\code{\textit{FinSet}}: &
A set of one or more fins. \\
\hspace{9mm}\code{TrapezoidalFinSet}: &
A set of trapezoidal fins. \\
\hspace{9mm}\code{EllipticalFinSet}: &
A set of elliptical fins. \\
\hspace{9mm}\code{FreeformFinSet}: &
A set of free-form fins. \\
\hspace{6mm}\code{LaunchLug}: &
A launch lug or rail pin. \\
\hspace{3mm}\code{\textit{InternalComponent}}: &
An internal component that may affect the mass of the rocket but not
its aerodynamics. \\
\hspace{6mm}\code{\textit{StructuralComponent}}: &
A structural internal component, with specific shape and density. \\
\hspace{9mm}\code{\textit{RingComponent}}: &
A hollow cylindrical component. \\
\hspace{12mm}\code{\textit{ThicknessRingComponent}}: &
A component defined by an outer radius and shell thickness. \\
\hspace{15mm}\code{InnerTube}: &
An inner tube. Can be used as a motor mount and can be clustered. \\
\hspace{15mm}\code{TubeCoupler}: &
A coupler tube. \\
\hspace{15mm}\code{EngineBlock}: &
An engine block. \\
\hspace{12mm}\code{\textit{RadiusRingComponent}}: &
A component defined by an inner and outer radius. \\
\hspace{15mm}\code{CenteringRing}: &
A ring for centering components. \\
\hspace{15mm}\code{Bulkhead}: &
A solid bulkhead (inner radius zero). \\
\hspace{6mm}\code{\textit{MassObject}}: &
An internal component shaped approximately like a solid cylinder and
with a specific mass. \\
\hspace{9mm}\code{MassComponent}: &
A generic component with specific mass, for example payload. \\
\hspace{9mm}\code{\textit{RecoveryDevice}}: &
A recovery device. \\
\hspace{12mm}\code{Parachute}: &
A parachute. \\
\hspace{12mm}\code{Streamer}: &
A streamer. \\
\hspace{9mm}\code{ShockCord}: &
A shock cord with a specified material and length. \\
\hline
\end{tabular}
\end{table}
Additionally three interfaces are defined for the components,
\code{MotorMount}, \code{Clusterable} and \code{RadialParent}.
Components implementing the \code{Motor\-Mount} interface, currently
\code{BodyTube} and \code{InnerTube}, can function as motor mounts and
have motors loaded in them. The \code{Clusterable} interface
signifies that the component can be clustered in various
configurations. Currently only the \code{InnerTube} component can be
clustered. Components and motors that are attached to a clustered
inner tube are automatically replicated to all tubes within the
cluster. The \code{RadialParent} interface allows inner components to
automatically identify their correct inner and outer radii based on
their parent and sibling components. For example, a coupler tube can
automatically detect its radius based on the inner radius of
the parent body tube.
Since the software functionality is divided into different packages,
all component similarities cannot be directly be exploited through
inheritance. For example, the method of drawing a nose cone shape
belongs to the \url{gui.rocketfigure} package, however, it can share
the same code that draws a transition. For these purposes, reflective
programming is used extensively. The code for drawing both nose cones
and transitions is provided in the class
\code{gui.rocketfigure.SymmetricComponentShapes}, while the simpler
body tube is drawn by the class \code{BodyTubeShapes}. The correct
class is derived and instantiated dynamically based on the component
class. This allows easily sharing functionality common to different
components while still having loose coupling between the rocket
structure, presentation, computation and storage methods.
\subsection{Aerodynamic calculators and simulators}
\label{sec-simulator-calculator}
One of the key aspects in the design of the simulation implementation
was extensibility. Therefore all aerodynamic calculation code is
separated in the package \code{aerodynamics} and all simulation code
is in the package \code{simulator}.
The basis for aerodynamic calculations is the abstract class
\code{Aerodynamic\-Calculator}, while the simulators are subclasses of
the \code{Flight\-Simulator} class. This allows adding new
implementations of the aerodynamic calculators and simulators
independently. For example, a simulator using Euler integration was
written in the early stages of development, and later replaced by the
Runge-Kutta~4 simulator. Similarly, a different method of calculating
the aerodynamic forces, such as CFD, could be implemented and used by
the existing simulators.
Similar abstraction has been performed for the atmospheric temperature
and pressure model by the abstract class \code{AtmosphericModel} and
different rocket motor types by the \code{Motor} class, among others.
\subsection{Simulation listeners}
\label{sec-listeners}
Simulation listeners are pieces of code that can dynamically be
configured to listen to and interact with a simulation while it is
running. The listeners are called after each simulation step, at each
simulation event and both when the flight conditions and aerodynamic
forces have been calculated. The listeners may simply gather flight
data for use outside the simulation or modify the rocket or simulation
during the flight. This allows great potential for extensibility both
internally and externally.
Listeners are used internally for various purposes such as retrieving
flight progress information when the user is running simulations and
cancelling the simulations when necessary. Implementing such
functionality otherwise would have required a lot of special case
handling directly within the simulation code.
Listeners can also be used to modify the simulation or the rocket
during its flight. The successor project of Haisun<75><6E>t<EFBFBD> will include
an active roll stabilization system, where a flight computer will
measure the roll rate using two magnetometers and use a PID controller
to adjust two auxiliary fins to cancel out the roll inevitably
produced by imperfections in the main fins. A simulation listener was
written that first simulated the PID controller purely in Java, which
modified the cant angle of the auxiliary fins during the simulation.
Later a similar listener interfaced the external flight computer
directly using a serial data link. The listener fed the flight data
to the controller which computed and reported the control actions back
to the simulator. This system helped identify and fix numerous bugs
in the flight computer software, which would have otherwise been
nearly impossible to fully test. It is expected that the simulation
listeners will be an invaluable tool for more ambitious model rocket
enthusiasts.
A listener is produced by implementing the \code{SimulationListener}
interface or by extending the \code{AbstractSimulationListener}
class. The UI includes the option of defining custom simulation
listeners to be utilized during flight simulation.
\subsection{Warnings}
\label{sec-warnings}
The aerodynamic calculations and simulations are based on certain
assumptions and simplifications, such as a low angle of attack and a
smooth, continuous rocket body. The rocket component architecture
makes it possible to create designs that break these assumptions.
Instead of limiting the options of the design, the aerodynamic
calculator and simulator can produce warnings about such issues.
These warnings are presented to the user during the design of the
rocket or after simulations. It is then left up to the user to judge
whether such violations are significant enough to cast doubt to the
validity of the results.
\subsection{File format}
An XML-based file format was devised for storing the rocket designs
and simulations. The use of XML allows using many existing tools for
reading and writing the files, allows easy extensibility and makes the
files human-readable. The user has the option of including all
simulated data in the file, storing the data at specific time
intervals or storing only the simulation launch conditions. To reduce
the file size, the files can additionally be compressed using the
standard GZIP compression algorithm~\cite{GZIP}. The files are
compressed and uncompressed automatically by the software. The file
extension .ORK was chosen for the design files, an abbreviation of the
software name that at the same time had no previous uses as a file
extension.
\section{User interface design}
The user interface was designed with the intent of being robust but
yet easy to use even for inexperienced users. The main window,
depicted in Figure~\ref{fig-main-window}(a) with the design of the
original Haisun<75><6E>t<EFBFBD> rocket, consists of a schematic drawing of the
rocket, the tree structure of the rocket components and
buttons for adding new components to the structure. Components can
be selected or edited by clicking and double-clicking either the tree
view or the component in the schematic diagram. The selected
components are drawn in bold to give a visual clue to the position
of the component.
The schematic drawing can be viewed either from the side or from the
rear, can be zoomed in and out and rotated along the centerline. The
schematic diagram view also presents basic information about the
rocket, such as the design name, length, maximum diameter, mass and
possible warnings about the design. It also calculates the CG and CP
positions continuously during design and shows them both numerically
and on the diagram. Additionally, a simulation is automatically run
in the background after each modification and the main results are
presented in the lower left corner of the diagram. Many users are
interested in the maximum altitude or velocity of the rocket, and this
allows an immediate feedback on the effect of the changes they are
making to the design. The flight information typically takes less
than a second to update.
The upper part of the main window can also be changed to view
simulation results, Figure~\ref{fig-main-window}(b). Many simulations
can be added with different launch conditions and motor configurations
to investigate their effects. Each simulation has a row which
presents the basic information about the simulation. The first column
gives an immediate visual clue to the status of the simulation; a gray
ball indicates that the simulation has not been run yet, green
indicates an up-to-date simulation, red indicates that the design has
been changed after the simulation was run and yellow indicates that
the simulation information was loaded from a file, but that the file
states it to be up-to-date. The simulations can be run one or several
at a time. The software automatically utilizes several threads when
running multiple simulations on a multi-CPU computer to utilize the
full processing capacity.
Figure~\ref{fig-various-dialogs} shows two dialogs that are used
to modify and analyze the designs. The components are edited using a
small dialog window that allows the user to either fill in the exact
numerical values specifying the shape of the component or use sliders
to modify them. The user can change the units by clicking on them, or
set default values from the preferences. Different tabs allow control
over the mass and CG override settings, figure color options, motor
mount and cluster options and more. The Component analysis dialog
shown in the figure can be used to analyze the effect of individual
components on the total stability, drag and roll characteristics of
the rocket.
Similarly, the launch conditions and simulator options can be edited
in the corresponding dialog. The simulator options also allow the
user to define custom simulation listeners to use during the
simulations. The simulation edit dialog is also used for later data
analysis. The simulated data can be plotted in a variety of ways as
shown in Figure~\ref{fig-plotting}. The user can use predefined plot
settings or define their own. Up to 15 different variables out of the
47 quantities computed can be plotted at a time. The variable on the
horizontal axis can be freely selected, and the other variables can be
plotted on one of two vertical axis, on either side of the plot. The
user can either specify whether a variable should plot on the left or
right axis or let the software decide the most suitable axis. Typical
plots include the altitude, vertical velocity and acceleration of the
rocket with time or the drag coefficient as a function of the Mach
number.
\begin{figure}
\hspace{-7mm}
\begin{tabular}{m{1mm}m{10cm}}
\hspace{-5mm}(a) &
\epsfig{file=figures/pix/openrocket-main-haisunaata,scale=0.5} \\
\hspace{-5mm}(b) &
\epsfig{file=figures/pix/openrocket-simulations-haisunaata,scale=0.5}
\end{tabular}
\caption{The main design window of OpenRocket; (a) the design
view and (b) the simulation view.}
\label{fig-main-window}
\end{figure}
\begin{figure}
\centering
\epsfig{file=figures/pix/openrocket-dialog-edit,scale=0.5}
\vspace{2cm} \\
\epsfig{file=figures/pix/openrocket-dialog-analysis,scale=0.5}
\vspace{1cm} \\
\caption{Dialog windows for editing the properties of a nose cone
and for analyzing the influence of individual components on
the stability, drag and roll characteristics of the rocket.}
\label{fig-various-dialogs}
\end{figure}
\begin{figure}
\centering
\epsfig{file=figures/pix/openrocket-dialog-plot-options,scale=0.5}
\vspace{2cm} \\
\epsfig{file=figures/pix/openrocket-dialog-plot,scale=0.5}
\vspace{1cm} \\
\caption{Dialog window for changing the simulation plot options and a
plot of the simulated flight of the Haisun<75><6E>t<EFBFBD> hybrid rocket.}
\label{fig-plotting}
\end{figure}
\section{Future enhancements}
Numerous features have been planned and taken into account during the
design of the software. Below are listed a few of the planned
features and how they have been taken into account:
{\it Alternative aerodynamic calculators.} For example CFD could be
used to calculate the aerodynamic properties, allowing even better
simulation accuracy. The calculators have been abstracted by the
\code{AerodynamicCalculator} class so they can easily be
interchanged.
{\it Alternative simulators.} These could take into account for
example the curvature of the Earth and include the Coriolis effect.
New simulators can be created by extending the abstract
\code{FlightSimulator} class.
{\it Export and import of flight data.} The simulated data could be
exported for further analysis as comma separated values (CSV).
Similarly, experimental data could be imported either from files or
directly from altimeters. Support for imported data already exists in
the core functionalities.
{\it Importing database files.} The motor database is easily
extendable to read external thrust curves. Also data of commercially
available rocket components could be imported and available in the
component edit dialog.
{\it Further UI enhancements.} These could include for example a 3D
view of the rocket, an animation of the rocket flight, a ``wizard''
dialog for easily creating new designs, {\it etc.}