Add some more pages
@ -1,7 +1,18 @@
|
||||
/* Change the ReadTheDocs theme */
|
||||
.wy-nav-content {
|
||||
max-width: 65% !important;
|
||||
}
|
||||
|
||||
.wy-side-nav-search, .wy-nav-top {
|
||||
background: #1d8be1;
|
||||
}
|
||||
|
||||
.wy-side-nav-search .logo {
|
||||
max-width: 42% !important;
|
||||
}
|
||||
|
||||
/* Custom OpenRocket CSS */
|
||||
|
||||
.or-figclass {
|
||||
text-align: center;
|
||||
}
|
||||
|
BIN
docs/source/_static/navbar-logo.png
Normal file
After Width: | Height: | Size: 63 KiB |
@ -20,6 +20,7 @@
|
||||
project = 'OpenRocket'
|
||||
copyright = '2024, OpenRocket team'
|
||||
author = 'OpenRocket team'
|
||||
github_url = 'https://github.com/openrocket/openrocket'
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '23.09'
|
||||
@ -44,6 +45,25 @@ exclude_patterns = []
|
||||
# user starts in light mode
|
||||
default_dark_mode = False
|
||||
|
||||
# -- Options for ReadTheDocs -------------------------------------------------
|
||||
|
||||
|
||||
html_theme_options = {
|
||||
#'analytics_id': 'G-XXXXXXXXXX', # Provided by Google in your dashboard
|
||||
#'analytics_anonymize_ip': False,
|
||||
'logo_only': False,
|
||||
'display_version': True,
|
||||
'prev_next_buttons_location': 'both',
|
||||
'style_external_links': True,
|
||||
'vcs_pageview_mode': '',
|
||||
# Toc options
|
||||
'collapse_navigation': True,
|
||||
'sticky_navigation': False,
|
||||
'navigation_depth': 3,
|
||||
'includehidden': True,
|
||||
'titles_only': False
|
||||
}
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
@ -57,6 +77,8 @@ html_theme = 'sphinx_rtd_theme'
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
html_logo = "_static/navbar-logo.png"
|
||||
|
||||
# Configure Sphinx to update the sidebar whenever the navigation data changes.
|
||||
html_context = {
|
||||
'navigation_update': True
|
||||
|
@ -2,6 +2,13 @@
|
||||
Codebase Walkthrough
|
||||
********************
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Important Modules and Packages
|
||||
==============================
|
||||
|
||||
|
@ -10,6 +10,8 @@ for our documentation, how to edit and build the documentation, and the style gu
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Why Sphinx?
|
||||
===========
|
||||
|
||||
|
After Width: | Height: | Size: 150 KiB |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 103 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 75 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 163 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 3.4 KiB |
BIN
docs/source/img/user_guide/advanced_rocket_design/ClusterAft.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
docs/source/img/user_guide/advanced_rocket_design/ClusterTab.png
Normal file
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 85 KiB |
BIN
docs/source/img/user_guide/advanced_rocket_design/RingTail.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
docs/source/img/user_guide/advanced_rocket_design/TubeFins.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
docs/source/img/user_guide/advanced_rocket_design/Unicon.png
Normal file
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 14 KiB |
@ -30,6 +30,11 @@ Welcome to OpenRocket's documentation!
|
||||
user_guide/basic_rocket_design
|
||||
user_guide/basic_flight_simulation
|
||||
user_guide/advanced_rocket_design
|
||||
user_guide/advanced_flight_simulation
|
||||
user_guide/overrides_and_surface_finish
|
||||
user_guide/rocket_analysis
|
||||
user_guide/custom_expressions
|
||||
user_guide/simulation_extensions
|
||||
user_guide/thrust_curves
|
||||
|
||||
.. toctree::
|
||||
|
@ -2,6 +2,15 @@
|
||||
Features
|
||||
********
|
||||
|
||||
This page lists the current features of OpenRocket and compares them to those of RockSim.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Current features (as of OpenRocket 23.09):
|
||||
==========================================
|
||||
|
||||
|
@ -13,6 +13,8 @@ the next section.
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
.. _the_user_interface:
|
||||
|
||||
The User interface
|
||||
|
@ -7,6 +7,8 @@ Installation Instructions
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
|
216
docs/source/user_guide/advanced_flight_simulation.rst
Normal file
@ -0,0 +1,216 @@
|
||||
**************************
|
||||
Advanced Flight Simulation
|
||||
**************************
|
||||
|
||||
OpenRocket offers more advanced options for simulating flight. You can plot your rocket's predicted acceleration, climb,
|
||||
eject and landing, make a prediction for how far downrange and in which direction your flight will land, and even
|
||||
experiment with different models of Earth's geometry, as it affects your flight. Once you're satisfied with a sim, you
|
||||
can export your data for analysis and charting in other packages.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Plotting your rocket's flight
|
||||
=============================
|
||||
|
||||
To begin learning about OpenRocket's plotting features, first, click the **Plot / Export** button on the **Flight simulations** window.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/PlotExportButton.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: The Plot / export Button.
|
||||
|
||||
On the **Edit simulation** panel, you'll see tabs marked **Plot data** and **Export data**.
|
||||
|
||||
Plotting data
|
||||
-------------
|
||||
|
||||
The **Plot data** tab opens first. Here you can define many parameters that will determine what values are plotted, and
|
||||
what events are marked on the plot.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/PlotExportWindow.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: The Plot / export window.
|
||||
|
||||
Here you'll be able to quickly choose from a number of standard plots:
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/PlotConfigs.png
|
||||
:width: 806 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: Standard plots
|
||||
|
||||
You'll also be able to assign to the X and Y axes any one of over 50 parameters:
|
||||
|
||||
- Time
|
||||
- Altitude
|
||||
- Vertical velocity
|
||||
- Vertical acceleration
|
||||
- Total velocity
|
||||
- Total acceleration
|
||||
- Lateral distance
|
||||
- Lateral direction
|
||||
- Lateral velocity
|
||||
- Lateral acceleration
|
||||
- Latitude
|
||||
- Longitude
|
||||
- Gravitational acceleration
|
||||
- Angle of attack
|
||||
- Roll rate
|
||||
- Pitch rate
|
||||
- Yaw rate
|
||||
- Mass
|
||||
- Propellant mass
|
||||
- Longitudinal moment of inertia
|
||||
- Rotational moment of inertia
|
||||
- CP location
|
||||
- CG location
|
||||
- Stability margin calibers
|
||||
- Mach number
|
||||
- Reynolds number
|
||||
- Thrust
|
||||
- Drag force
|
||||
- Drag coefficient
|
||||
- Axial drag coefficient
|
||||
- Friction drag coefficient
|
||||
- Pressure drag coefficient
|
||||
- Base drag coefficient
|
||||
- Normal force coefficient
|
||||
- Pitch moment coefficient
|
||||
- Yaw moment coefficient
|
||||
- Side force coefficient
|
||||
- Roll moment coefficient
|
||||
- Roll forcing coefficient
|
||||
- Roll damping coefficient
|
||||
- Pitch damping coefficient
|
||||
- Reference length
|
||||
- Reference area
|
||||
- Vertical orientation (zenith)
|
||||
- Lateral orientation (azimuth)
|
||||
- Wind velocity
|
||||
- Air temperature
|
||||
- Air pressure
|
||||
- Speed of sound
|
||||
- Simulation time step
|
||||
- Computation time
|
||||
- Position parallel to wind
|
||||
- Position upwind
|
||||
|
||||
You can assign multiple parameters to the Y-axis, and choose whether their scales appear on the left, or the right side
|
||||
of the plot. You can add Y-axis parameters with the **New Y-axis plot type** button, or delete parameters from the plot
|
||||
with the **X** buttons. *(The X-axis takes only a single plotted parameter, typically **Time**).*
|
||||
|
||||
Additionally, you can choose from several flight events, any or all of which can be called out on your plot, in reference
|
||||
to the simulated time of occurrence.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/YaxisTypes.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: Setting Y-axes and Events for plotting
|
||||
|
||||
Plotted results
|
||||
---------------
|
||||
|
||||
Below you can see a plot of *A simple model rocket*, simulation number 4, flying on a C6-5. Note that the five events
|
||||
checked in the above screen have been marked on the plot (*some very close to each other, or to the edge*):
|
||||
**Motor ignition**, **Motor burnout**, **Apogee**, **Recovery device deployment**, and **Ground hit**.
|
||||
|
||||
You can also see that the three Y-axis parameters described above: **Altitude**, **Vertical velocity**, and
|
||||
**Vertical acceleration** appear as lines of three different colors.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/PlotOfSimulation.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: A Plot of the simulation.
|
||||
|
||||
As your rockets get more complex, with features like dual-deploy, air-start and multiple stages, your plots can grow in
|
||||
complexity to simulate their expected behavior. Below is a plot (*from the example rockets*) of a "High Power Airstart"
|
||||
rocket, modeled after a Patriot missile. The central motor starts on the launch pad, while the surrounding motors start
|
||||
while the rocket is in the air (*hence, an "airstart"*). The plot records the separate motor start events, and the
|
||||
deployment of both a drogue, and a main parachute.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/ComplexPlot.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: A Plot of Sim #5 of the "High Power Airstart" example rocket.
|
||||
|
||||
Notice what's happening in the plot above: The rocket is *losing velocity* - the blue line - before the airstart occurs.
|
||||
This is probably not what we want.
|
||||
|
||||
However, simulation number 3 of the same rocket, below, has an earlier airstart, and looks like it should work as expected.
|
||||
Looking at the slight wiggle in the velocity curve, we could also try another simulation to provide a little bit more
|
||||
margin for error.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/ComplexPlot2.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: A Plot of Sim #3 of the "High Power Airstart" example rocket.
|
||||
|
||||
Launch Conditions and Simulation Options
|
||||
========================================
|
||||
|
||||
From the **Plot data** window, you can click the **<< Edit** button to configure **Launch conditions**, and
|
||||
**Simulation options** before you plot.
|
||||
|
||||
Launch conditions
|
||||
-----------------
|
||||
|
||||
OpenRocket can simulate conditions at the launch site, so you can estimate how winds will direct your flight, and how
|
||||
far downrange your rocket will drift.
|
||||
|
||||
In the screen shown below, you can set parameters (and units) for wind, and for your **Launch site**, you can set the
|
||||
**Latitude**, **Longitude** and **Altitude**, as well as **Atmospheric conditions**. Note that Atmospheric conditions
|
||||
affect your rocket's ascent velocity, as well as the local [Speed of Sound](https://en.wikipedia.org/wiki/Speed_of_sound).
|
||||
|
||||
This is also the panel where you can set the length of your launch rod or rail. This length will affect whether your
|
||||
simulation *passes or fails*, when it's evaluated for minimum speed off the rod.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/EditSimulationLaunchCond.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: The Edit simulation window: Launch conditions.
|
||||
|
||||
Simulation options
|
||||
------------------
|
||||
|
||||
In the **Simulation options** tab, the **Simulator options** let you choose the shape of the simulated Earth in your
|
||||
calculations (*doing so **does not** affect the Earth background in Photo Studio*), and you can choose the time-resolution
|
||||
of the simulation. This is also the place where you add and set up **Simulation extensions**, which are beyond this
|
||||
guide's purpose (*and frankly, beyond this author's knowledge!*).
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/EditSimulationSimOpts.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: The Edit simulation window: Simulation options.
|
||||
|
||||
Exporting Data
|
||||
==============
|
||||
|
||||
Located on the Plot / export panel, the Export Data tab (shown below) helps you set up a Comma-Separated Value (.csv)
|
||||
formatted file to export data from your simulations. You can export any or all of over 50 values (generally speaking,
|
||||
the list of parameters above, plus **Coriolis acceleration**). Optional **Comments** sections list any flight events
|
||||
(**Apogee**, for example) you selected for your simulation, as well as description and field descriptions.
|
||||
|
||||
You can choose separators other than comma, if you prefer semicolon, space, or TAB-delimited data. Once you have your
|
||||
data choices set up, clicking the **Export** button brings up a file dialog to choose a filename and location for your
|
||||
exported data.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_flight_simulation/ExportData.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: The Export data window.
|
||||
|
@ -1,3 +1,535 @@
|
||||
**********************
|
||||
Advanced Rocket Design
|
||||
**********************
|
||||
|
||||
In this section, advanced design principles and concepts are discussed, with step-by-step instructions describing how to
|
||||
incorporate these techniques into designs created in *OpenRocket*. Implementing the techniques described in this section
|
||||
may require specialized materials and electronic devices intended for use only by experienced rocketeers.
|
||||
|
||||
Advanced rocket design encompasses configurations for high power rockets generally, including:
|
||||
|
||||
- recovery systems
|
||||
- through-the-wall fin construction
|
||||
- electronic and dual deployment
|
||||
- complex multi-staging (such as motor racking) and motor clustering
|
||||
- roll stabilization
|
||||
|
||||
Additionally, you may find that using mass and center of gravity (CG) overrides will improve *OpenRocket* flight and
|
||||
recovery simulation accuracy.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Recovery Systems
|
||||
================
|
||||
|
||||
Recovery Techniques
|
||||
-------------------
|
||||
|
||||
Recovery systems are intended to return a rocket safely to the ground, without harm to people or damage to the rocket or
|
||||
other objects. Though recovery mechanisms vary greatly, recovery systems generally include elements of one or more of
|
||||
these techniques:
|
||||
|
||||
- featherweight
|
||||
- break-apart
|
||||
- streamer
|
||||
- parachute
|
||||
- helicopter
|
||||
- gliding
|
||||
|
||||
Featherweight and Break-Apart Recovery
|
||||
--------------------------------------
|
||||
|
||||
Featherweight and break-apart recovery work by creating enough drag to ensure that the terminal velocity of the rocket
|
||||
is so low that it won't be damaged or do damage when it hits the ground. Featherweight designs are often minimum diameter
|
||||
rockets that eject the burned-out motor casing altogether, or use the ejection charge to shift the casing position
|
||||
rearward after motor burnout (within an extended motor hook), to induce instability and cause the rocket to tumble.
|
||||
Break-apart recovery, aerodynamically, does the same thing, increasing drag and inducing instability by breaking the
|
||||
rocket into two or more sections connected together by a shock cord. Typically, a featherweight rocket, and each section
|
||||
of a break-apart rocket weighs less than one ounce.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_rocket_design/Featherweight.png
|
||||
:width: 245 px
|
||||
:align: left
|
||||
:figclass: or-image-border
|
||||
:alt: The Estes Astron Streak, ca 1970 - a *featherweight recovery* rocket
|
||||
|
||||
Example Featherweight Design
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In earlier years, Estes sold a few rockets that featured *Featherweight Recovery*, meaning that a very light model could
|
||||
spit out its used motor casing, and land directly on the ground with no damage, rather like a badminton shuttlecock.
|
||||
|
||||
Ejecting burned-out motor casings is not allowed in NAR contests unless a streamer or parachute is attached to the
|
||||
ejected casing.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_rocket_design/Unicon.png
|
||||
:width: 200 px
|
||||
:align: right
|
||||
:figclass: or-image-border
|
||||
:alt: The scratch Unicon, ca 1970 - a *break-apart recovery* rocket
|
||||
|
||||
Example Break-Apart Design
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Another approach to bringing a lightweight rocket safely to earth is to break the airframe into several aerodynamically
|
||||
unstable pieces, and "flutter" them back to earth.
|
||||
|
||||
One such design: the **[Unicon](https://archive.org/details/american-aircraft-modeler-02-1970/page/n41/mode/2up)**
|
||||
(for *"Unified/Consolidated"* - a stretch, I know) appeared as a plan in American Aircraft Modeler in February, 1970.
|
||||
The body tube featured 3 pieces of launch lug, as did the nose cone. Into these lugs plugged one of 3 balsa sticks, each
|
||||
of which held a fin, and a piece of body tube attached to the fin root and the stick, to provide a stable anchor against
|
||||
the body. The entire assembly was connected with pieces of heavy-duty thread.
|
||||
|
||||
When the ejection charge fired, the nose cone popped off, releasing the sticks with fins, which, tied to the body tube
|
||||
and nose cone, fluttered in the air, and slowed descent of the main airframe as it landed.
|
||||
|
||||
This author built one, and it worked pretty well.
|
||||
|
||||
Streamer and Parachute Recovery
|
||||
-------------------------------
|
||||
|
||||
Streamers and parachutes add drag to slow the rocket descent rate. Generally, a larger streamer is always better. But,
|
||||
streamer size is an example of the principle of diminishing marginal returns, eventually making a streamer larger will
|
||||
only slightly increase drag (a rocket weighing more than 10 oz is beyond the effective use of a streamer). On the other
|
||||
hand, because of their efficiency, parachutes create more drag with less cloth than any other method, and virtually all
|
||||
high power rockets use parachutes.
|
||||
|
||||
Example Streamer Design
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A method of recovery favored on windier days is to attach a flame-retardant streamer to the shock cord, in place of a chute.
|
||||
Using *OpenRocket* you can simulate streamer recovery by equipping your rocket design with a streamer from the **Mass objects** section.
|
||||
|
||||
A streamer flaps in the wind as the rocket falls, losing altitude faster than an equivalent volume of packed parachute.
|
||||
Because it comes in faster, it won't drift as much in the wind. The rocket will also hit harder, potentially risking damage.
|
||||
*OpenRocket* can help you estimate how fast your model will land.
|
||||
|
||||
By using "snap swivels" - small brass clips usually found in the fishing tackle aisle - you can prepare both a parachute
|
||||
and a streamer for a rocket, choose your method of recovery at the field, and clip it onto the shock cord before you launch.
|
||||
|
||||
NAR requires 10 square cm of streamer area per gram of mass in contest models.
|
||||
|
||||
Example Parachute Design
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Parachute recovery is probably the most familiar model rocket recovery mechanism. Most of the beginner kits start with
|
||||
parachutes, but even high-power, edge-of-space-kissing, multi-stage, electronic deployment rockets use parachutes to
|
||||
slow descent. They're basic to the hobby.
|
||||
|
||||
*OpenRocket* gives you a number of simulation options for parachutes, including material, construction, size, number of
|
||||
shroud lines, packed size and more. With *OpenRocket*, you can set your parachute's deployment to work just like your
|
||||
real rocket's.
|
||||
|
||||
One thing that you're not able to directly simulate here is the *type* of 'chute you have. Parachutes come in different
|
||||
types, from the semi-ellipsoid proper Parachute - an efficient shape (by drag to weight) which cannot be laid perfectly
|
||||
flat, to the "parasheet" - a 'chute that can be formed from a flat piece of material (the typical model rocket kit
|
||||
contains a parasheet), to X-shaped parachutes, to 'chutes with spill-holes, to parafoils and Rogallo wings. You'll have
|
||||
to experiment with these chutes, and perhaps try and adjust the Drag coefficient to compensate for difference from
|
||||
*OpenRocket*'s ideal parachute.
|
||||
|
||||
NAR requires 5 square cm of parachute area per gram of mass in contest models.
|
||||
|
||||
In 2022, Apogee released a "Gliding Parachute", which could be steered by remote control back to the launch pad (given
|
||||
enough altitude and favorable winds). OpenRocket cannot, at this writing, simulate the behavior of the Gliding Parachute.
|
||||
|
||||
Helicopter and Gliding Recovery
|
||||
-------------------------------
|
||||
|
||||
Helicopter Recovery
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Helicopter recovery relies upon rigid lift-generating blades and auto-rotation to slow terminal velocity. This design
|
||||
technique is the most complicated of all, and requires that the entire rocket be designed around the recovery device.
|
||||
As important, the stresses generated by rapidly spinning blades hitting the ground effectively limits the use of this
|
||||
technique to low mass (model) rockets.
|
||||
|
||||
Gliding Recovery
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
A glider uses aerodynamic lift to control terminal velocity. However, because the aerodynamic requirements of vertical
|
||||
flight are vastly different than gliding flight, to make this transition there must be a shift in the center of gravity
|
||||
or the center of pressure. This transition can be made by reducing mass (ejecting the motor mount tube and weights) or
|
||||
changing aerodynamic signature (ejection activated fin-elevators or swing-wings). Radio and other control systems are
|
||||
currently being used to fly gliding recovery rockets, even high power.
|
||||
|
||||
Protecting Recovery Components
|
||||
-------------------------------
|
||||
|
||||
Recovery components are made from lightweight materials which, while often flame retardant, aren't necessarily heat-proof,
|
||||
or which may char and decay without bursting into flame.
|
||||
|
||||
To protect the recovery components and ensure they work properly for a safe landing, some method of shielding the
|
||||
"Laundry" (slang for the parachute and associated cords) from the heat of ejection, or of cooling the eject gasses must
|
||||
be used.
|
||||
|
||||
Heat Shields
|
||||
------------
|
||||
|
||||
Protecting the components starts during rocket design: you can choose something durable and flame-resistant like Kevlar
|
||||
cord for shock cord components that will be used in the eject area. A little later in this article, you'll see other
|
||||
built-in options you can use.
|
||||
|
||||
Fire Resistant Wadding and Blankets
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The simplest way to protect the 'chute is to put something flameproof between the eject charge and the recovery hardware.
|
||||
In small rockets, this can take the form of "Flameproof ejection wadding", as packaged with Estes motors, or flame-retardant
|
||||
recycled cellulose insulation (nicknamed "Dog Barf" in the hobby community). Of the two, "Dog Barf" makes much less of a
|
||||
mess on the field, and is recommended by some clubs. If you do use "Estes Flameproof ejection wadding", please try and
|
||||
recover as much of the discarded paper as possible before leaving your launch site.
|
||||
|
||||
When using wadding, try and put in a minimum depth of 1.5 tube diameters of wadding. Wadding may be poked gently into a
|
||||
rocket with a pencil or stick, but don't pack it down.
|
||||
|
||||
You can also buy a reusable 'chute protector, called a "Nomex blanket" or a "'Chute bag" (also made of Nomex). Nomex
|
||||
blankets are typically square, often orange, and usually have a buttonhole sewn into the corner, to pass the shock cord
|
||||
through. One wraps up the parachute and as much of the shock cord as is practical with the Nomex facing the eject charge.
|
||||
This author was instructed to wrap the 'chute in Nomex "Like a burrito", but in reality there are several ways to pack a
|
||||
chute protector that will work well. Ensure that the Nomex faces the eject charge, so it takes the heat of ejection, and
|
||||
not your recovery device.
|
||||
|
||||
Nomex can be re-packed with the 'chute immediately after a flight. Nomex is machine-washable (and you'll probably want
|
||||
to wash it at some point).
|
||||
|
||||
**A rule of thumb for sizing a Nomex blanket**: *The blanket should be a square, with a width that's 3 times the body diameter.*
|
||||
|
||||
Piston Ejection
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Another way of insulating the recovery material from the heat of ejection is with a Piston Ejection system.
|
||||
|
||||
In a typical piston ejection system, a piston is inserted into the body tube, and is free to slide up and down the tube's
|
||||
length. The eject charge is on one side of the piston, and the recovery material on the other. The body tube, the piston
|
||||
and the recovery material are all connected together, so as not to lose any parts.
|
||||
|
||||
At ejection charge firing, expanding gases push the piston (and the recovery material) up the tube and out of the rocket,
|
||||
without exposing the recovery material to the heat of the eject charge. The piston should leave the rocket body, in order
|
||||
to vent the ejection gases.
|
||||
|
||||
Pistons are often made of tube couplers, which have been sanded down a bit to smoothly slide in the body tube. One end of
|
||||
the coupler is closed by a bulkhead. The closed end is called the "face" of the piston. The rounded wall of the coupler
|
||||
is called the piston's "skirt".
|
||||
|
||||
The attachment shock cord runs from the eject charge end of the rocket, attaches to the piston at the face (or is threaded
|
||||
through it and sealed) and more shock cord runs from the other side of the piston face and to the recovery material.
|
||||
The attachment cord needs to be long enough for the piston to escape the body tube so exhaust gases are vented. The
|
||||
piston *must* move smoothly and without sticking; if the piston sticks, the parachute may not be deployed.
|
||||
|
||||
Opinions differ on whether the "face" of the piston should face the 'chute or the ejection charge. According to one theory,
|
||||
if the piston face is on the nose cone side of the piston, exhaust gases could make the piston skirt swell and cause the
|
||||
piston to stick in the body tube, while if instead the piston faces the eject charge, eject gases that travel between the
|
||||
piston skirt and the inside of the body tube form a "gaseous lubricant" which should prevent the piston from getting stuck.
|
||||
Others beg to differ, and have had successful real world experience with the piston facing upward.
|
||||
|
||||
Ejection Gas Cooling
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Another approach to protecting the recovery material is to cool the ejection gases before they contact the 'chute.
|
||||
|
||||
Cooling Mesh
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Aerotech sells a metal cooling mesh for model rockets. The mesh looks like a tiny tangled slinky, or perhaps like twisted
|
||||
tinsel from a Christmas tree. Installing a metal cooling mesh in the rocket body allows cooling of the exhaust gases,
|
||||
which transfer much of their heat to the metal mesh as they pass. The configuration of the mesh also makes it something
|
||||
of a particle filter, so chunks of burning material from the ejection charge get filtered out, instead of passing their
|
||||
heat to your parachute.
|
||||
|
||||
Baffles
|
||||
^^^^^^^
|
||||
|
||||
Still another approach is to install a baffle in the rocket, above the eject charge, and below the recovery system. A
|
||||
baffle is often made from a coupler with two bulkheads, one in each end. Designs differ, but basically there's a hole
|
||||
pattern in the top, and a hole pattern in the bottom, such that ejection gas will pass through, but because the holes
|
||||
don't align, it will need to make a detour through the baffle. Meanwhile, heavier burning solid material from the eject
|
||||
charge has much higher inertia, and won't be able to divert to the top set of holes. Much of it will be stopped by the
|
||||
top bulkhead.
|
||||
|
||||
Servicing
|
||||
^^^^^^^^^
|
||||
|
||||
Both baffles and cooling mesh will have limited lifespans, and need to be cleaned, serviced, or replaced. Cooling mesh in
|
||||
particular can become clogged with particles from many flights, and may be placed in a difficult-to-reach position.
|
||||
Baffles may burn, break, or get filled with particles. When this happens, the best service option may be to "poke out"
|
||||
the cooling mesh or baffle, and go over to recovery wadding or a Nomex blanket.
|
||||
|
||||
One way to avert the "poke out" problem is to use screws to attach a baffle through the wall of the body tube. Nylon
|
||||
screws may be used to avoid placing "ductile metal" in the airframe. Screw attachment allows the baffle to be removed
|
||||
for servicing or replacement.
|
||||
|
||||
CO\ :sub:`2`\ Ejection Devices
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Another approach to eject is pioneered by **[Tinder Rocketry](https://www.tinderrocketry.com/)**, who offer a CO\ :sub:`2`\
|
||||
ejection system. Because a minimal pyro device is used to trigger the CO\ :sub:`2`\ ejection, there's not a lot of hot
|
||||
material flying around inside the airframe, and no need for wadding or a Nomex blanket. The CO\ :sub:`2`\ is cold as it's released.
|
||||
|
||||
The CO\ :sub:`2`\ ejection system is claimed to operate more reliably than black powder at extreme altitude
|
||||
(above 20,000 feet ASL), due to black powder's incomplete or non-existent burn at these altitudes.
|
||||
|
||||
Tube Fins and Ring Tails
|
||||
========================
|
||||
|
||||
Tube Fins
|
||||
---------
|
||||
|
||||
A tube fin is just that, a fin made using a shorter section of body tube, adhered to the main body tube, with or without
|
||||
other flat fins. This type of rocket is easy enough to build, and OpenRocket helps you make an accurate simulation.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_rocket_design/TubeFins.png
|
||||
:width: 250 px
|
||||
:align: right
|
||||
:figclass: or-image-border
|
||||
:alt: *A simple model rocket* - now with tube fins.
|
||||
|
||||
Let's convert *A Simple Model Rocket* from 3 flat fins, to 4 tube fins, just because we can.
|
||||
|
||||
1. From the **File** menu, choose **Open Example** and open **A simple model rocket**.
|
||||
2. Left-click on the **Trapezoidal fin set** in the upper-left panel, and delete it.
|
||||
3. Left-click on the **Body tube**.
|
||||
4. Note that **Tube fins** is now enabled in **Body components and fin sets**. Click it.
|
||||
5. The number of fins defaults to 6. These look a little long. Drag the **length** slider until the fins are about 7cm long.
|
||||
6. Drag the **plus** slider (under **Position relative to:**) to move the fins forward just a little.
|
||||
7. Leave the **Tube fin set configuration** window open, and click on the **View Type** menu on the main window.
|
||||
Choose the **Back view**.
|
||||
8. Notice that OpenRocket has defaulted to an exact solution for wrapping 6 tube fins around your rocket body tube.
|
||||
In the **Tube fin set configuration** window, drag the **Fin rotation** slider until they line up with the launch lug.
|
||||
(*Passing the launch rod through one of the tube fins to reach the launch lug is simpler than arranging the tube fins
|
||||
for the rod to pass between the tubes*)
|
||||
9. Notice that you can adjust the Outer Diameter of the fins to create designs that are harder to build, or perhaps
|
||||
impossible to build due to overlaps between tube fins.
|
||||
10. Click the **Automatic** check box beneath **Outer diameter**. The tubes conform once more to the body tube and touch
|
||||
each other. Because the contact surfaces are in the right place to adhere to each other, this is probably the easiest
|
||||
type of fin configuration to build.
|
||||
11. Reduce the **Number of fins** to 5, then to 4. As long as **Automatic** is checked and the solution makes sense,
|
||||
the fins will wrap the body tube. At 4 fins, the tubes would have to dwarf the body tube to wrap it, and OpenRocket
|
||||
gives up on wrapping.
|
||||
12. Re-adjust the **Fin rotation** slider to line the 4-fin set up with the launch lug, either within, or beside a tube fin.
|
||||
|
||||
Our fin conversion is complete, but before we leave the **Tube fin set configuration** window, note a few other details:
|
||||
|
||||
- You can select preset tube components from the **Select preset** menu in the upper-right. If you choose **From database...**
|
||||
you can pick from a wide variety of components for your tube preset. *Note that these components represent what was
|
||||
available at the time this version of the OpenRocket component database was released - some may no longer be available*.
|
||||
Some details of the components will fill fields of the **Tube fin set configuration** window, but *Diameter* is not one
|
||||
of them - at least in OpenRocket 15.03.
|
||||
- It's not possible to use the **Tube fins** component to create tube fins sliced at an angle, or to create semi-circular
|
||||
fin sections (tubes cut in half, lengthwise).
|
||||
- Though you might imagine lots of cool tube fin scenarios, this Tube fin tool will require your tubes to be in side-to-side
|
||||
contact with a body tube.
|
||||
- OpenRocket won't apply your specified color to the inside of the tube fins. They'll have the default color inside.
|
||||
|
||||
Ring Tails
|
||||
----------
|
||||
|
||||
It's easy to visually add a ring tail fin to an OpenRocket model using a body tube, but there's one catch: the ring tail
|
||||
must start at the exact aft-end of the body tube it surrounds, and the supporting fins must trail to support it. This is
|
||||
because, unlike other non-external components in OpenRocket, external airframe parts follow a strict linear pattern:
|
||||
Nose cone, then a body tube, then perhaps another, and perhaps another, etc. If you don't want the ring tail fin at the
|
||||
end of the model, also visually simulate a ring tail virtually at any point up or down the airframe using an inner tube.
|
||||
But, as with the body tube approach, there’s a catch, inner tubes are aerodynamically ignored during the simulation.
|
||||
|
||||
**If you like the "look" of ring tail models, *OpenRocket does that very, very well*. Just **BE AWARE** that
|
||||
*OpenRocket WILL NOT accurately simulate ring tail fins* at this time.**
|
||||
|
||||
.. figure:: /img/user_guide/advanced_rocket_design/RingTail.png
|
||||
:width: 250 px
|
||||
:align: right
|
||||
:figclass: or-image-border
|
||||
:alt: *A simple model rocket* - with added Ring Tail.
|
||||
|
||||
So, if you want that ring tail "look," let's step through adding a ring tail to **A simple model rocket** to demonstrate
|
||||
the body tube method.
|
||||
|
||||
1. From the **File** menu, choose **Open example...** and choose **A simple model rocket**.
|
||||
2. Click the **Body tube** component to add a new body tube. *Note that it's added at the aft end of the main body tube,
|
||||
and is initially the same diameter as that tube*.
|
||||
3. Increase the tube's **Outer diameter** to 8.6cm, to let it just sit on the top fin. Yes, this will look strange for a moment or two.
|
||||
4. Reduce the **Body tube length** to 2.5cm, so the back of the ring tail just touches the back of the fin points.
|
||||
5. Set the appearance, if you'd like. Good choices for this model are White, and 50% **Shine**. *Note that since OpenRocket
|
||||
thinks this is a regular body tube, the inside of the ring tail won't receive your selected color.*
|
||||
6. Close the Body tube configuration window, and switch the **View Type:** menu to **Back view**. You should see the ring
|
||||
tail surrounding and touching the fins.
|
||||
7. You can look at the rocket in a **3D** View, or in **Photo studio** to see how it will look in the real world.
|
||||
|
||||
Your ring tail is complete.
|
||||
|
||||
In addition to not being able to accurately simulate this model, it's important to note that *the body tube ring tail
|
||||
**will give you** a "Discontinuity in rocket body diameter" warning too*.
|
||||
|
||||
Through-the-Wall Fin Mounting
|
||||
=============================
|
||||
|
||||
Model rocket fins are usually glued to the surface of an airframe. However, when higher thrust motors are used (E and
|
||||
above) the increased thrust can literally rip fins off or shoot a motor up through the airframe. Instead,
|
||||
"through-the-wall" (TTW) mounting refers to fins that protrude through a slot in the airframe and are glued to the motor
|
||||
mount tube, one or more centering rings, and the airframe surrounding the slot. This construction technique significantly
|
||||
strengthens fin joints and motor mounts.
|
||||
|
||||
There are three measurements necessary to create a fin tab: tab length, tab height, and tab position.
|
||||
|
||||
- **Tab length** is the distance from one side of the fin tab to the other. This is also the length of the slot that is
|
||||
cut through the airframe, the distance between the inside edges of the outermost centering rings.
|
||||
- **Tab height** is the distance from outside of the airframe to the outside of the motor mount tube. This is calculated
|
||||
as follows: (BT OD - MMT OD) / 2, where BT is the airframe body tube and MMT is the motor mount tube diameters.
|
||||
- **Tab position** is the distance from the root chord reference point to the fin tab reference point. *OpenRocket* features
|
||||
three choices:
|
||||
|
||||
Relative to:
|
||||
|
||||
- **the chord root leading edge** – the tab position is the distance from the fin chord root leading edge to the fin tab leading edge.
|
||||
- **the chord root midpoint** – the tab position is the distance from the fin chord root midpoint to the fin tab midpoint.
|
||||
- **the chord root trailing edge** – the tab position is the distance from the fin chord root trailing edge to the fin tab trailing edge.
|
||||
|
||||
*OpenRocket* will automatically calculate fin tab dimensions, within the following constraints:
|
||||
|
||||
- If there are no centering rings beneath a fin, the trailing edge of the fin tab is the fin chord trailing edge and the leading edge of the fin tab is the fin chord leading edge.
|
||||
- If only one centering ring is beneath a fin, the trailing edge of the fin tab is the fin chord trailing edge and the leading edge of the fin tab is the trailing edge of the centering ring.
|
||||
- If two centering rings are beneath a fin, the trailing edge of the fin tab is the leading edge of the trailing centering ring and the leading edge of the fin tab is the trailing edge of the leading centering ring.
|
||||
- If more than two centering rings are beneath a fin, referring to the centering rings in order from the trailing edge to the leading edge of the fin chord, the trailing edge of the fin tab is the leading edge of the first centering ring and the fin tab leading edge is the trailing edge of the second centering ring. *OpenRocket* supports only one fin tab on each fin.
|
||||
|
||||
Converting a simple rocket to through-the-wall design:
|
||||
|
||||
1. At the *OpenRocket* **main window**, left-click the **File** menu, then left-click **Open example design** in the drop-down menu.
|
||||
2. In the pop-up **Open example design** box, left-click the "*A simple model rocket*" selection, then left-click the **Open** button.
|
||||
3. In the **Rocket design** view, double left-click the **Trapezoidal fin set** component.
|
||||
4. Left-click the **Fin tabs** tab.
|
||||
5. Left-click the **Calculate automatically** button.
|
||||
|
||||
And, a through-the-wall fin tab is automatically created between the two motor mount centering rings.
|
||||
|
||||
Electronic and Dual Deployment
|
||||
==============================
|
||||
|
||||
<<INSERTION POINT>>
|
||||
|
||||
Clustering and Multi-staging
|
||||
============================
|
||||
|
||||
Complex rockets fall into two basic categories, a rocket that is propelled by a cluster of motors intended to be simultaneously ignited or multi-staged (massively-staged), propelled by a series of motors that successively ignite the next in line when the prior motor burns out.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_rocket_design/xkcd_whatif_24_model_suborbital.png
|
||||
:width: 392 px
|
||||
:align: left
|
||||
:figclass: or-image-border
|
||||
:alt: From [xkcd 'what if' #24](https://what-if.xkcd.com/24/): *How many model rocket engines would it take to launch a real rocket to space?*, a 65,000 motor staged-and-clustered rocket. Recommended reading for all rocketeers.
|
||||
|
||||
Motor Clustering
|
||||
----------------
|
||||
|
||||
Clustering refers to launching a rocket with more than one simultaneously-ignited rocket motor. Clustering is common in "real" aerospace programs. Familiar American examples include: the [Gemini Titan](https://en.wikipedia.org/wiki/Titan_II_GLV) - a two-motor cluster, the [Saturn V](https://en.wikipedia.org/wiki/Saturn_V#S-IC_first_stage) - a cluster of five Rocketdyne F-1 motors driving the first stage, and the [Falcon 9](https://en.wikipedia.org/wiki/Falcon_9#Launcher_versions) - a cluster of 9 Merlin motors driving the main stage.
|
||||
|
||||
In model and high-power rocketry, typical clusters seen are **2-motor**, always side-by-side, due to the geometry, **3-motor**, in a triangle or straight line, **4-motor**, in a square, and **5-motor**, typically arranged with one central motor surrounded by 4 in a square - though other arrangements are possible. There's nothing preventing much larger ones, but 2, 3, 4 and 5 are most-often seen.
|
||||
|
||||
In three- and five-motor clusters, it's not uncommon to see a larger or higher-power central motor, surrounded by smaller or weaker motors. This may be done for effect, or due to modeling constraints, or to more closely resemble its full-scale inspiration, or possibly for reasons of cost. Clustered motors may be "canted" - that is, pointed to the outside of the rocket fuselage's circumference, for effect, stability, or spin.
|
||||
|
||||
Designing a Rocket with Clustered Motors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
OpenRocket makes it easy to design motor clusters. To begin with, add an **Inner Tube** to your aft-most **Body Tube**. On the **Motor** tab, check the "This component is a motor mount" box. Set its inner diameter to one of the standard motor sizes, unless you have a unique need: 13, 18, 24, 29, 38, 54, 75 or 98mm. Next, click on the **Cluster** tab.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_rocket_design/ClusterTab.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: OpenRocket's **Cluster** tab
|
||||
|
||||
The **Cluster** tab lets you choose a common cluster configuration, and adjust it in your model. When you make an **Inner Tube** a cluster, you treat every tube in the cluster identically with each addition. If you add an **Engine block** or a **Mass component**, all of the tubes in the cluster will receive one.
|
||||
|
||||
First, pick a cluster configuration from the image tiles on the left side of the tab. Realize that depending upon the sizes of your motor tube and body tube, not every cluster that you can make will fit.
|
||||
|
||||
Next, adjust the **Tube separation**. This value controls how close the clustered motors are to each other. A value of 1 places the tubes in contact with each other. You can enter decimals like "1.25" in the separation field. In addition to potentially affecting your rocket's stability, the **Tube separation** you choose may influence the difficulty of wiring your clustered motors for ignition, and your ability to place adhesive and parts around tightly-packed tubes during construction.
|
||||
|
||||
.. figure:: /img/user_guide/advanced_rocket_design/ClusterAft.png
|
||||
:width: 800 px
|
||||
:align: center
|
||||
:figclass: or-image-border
|
||||
:alt: Clustered motor mounts, viewed from aft.
|
||||
|
||||
The **Rotation** setting rotates your cluster around the major axis of your rocket (the Up <--> Down one). It's used to line up the motors with other decorative and structural components of your rocket. This alignment may be critical if you're creating a design that ducts eject gasses from one part of the rocket to another.
|
||||
|
||||
The **Split cluster** button changes this component from a clustered motor component that can be handled as a unit, to individual motor tubes, which may be positioned and edited independently of each other. Once you split the cluster, items and settings you change for each tube will not automatically be added to the other tubes in the cluster. You may want this option if you have motor mount tubes of different lengths or diameters in the cluster. *Once split, a cluster cannot be recombined*. You must re-create the cluster as a unit if you'd like to revert to that approach.
|
||||
|
||||
Igniting a Cluster
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Important to the stability of the rocket's flight is that all the motors ignite more or less simultaneously. The initial concerns here are that all the motors' igniters are wired to take a single application of voltage from the launch controller, and that the controller be able to provide adequate voltage and current to ignite all the motors.
|
||||
|
||||
Estes Rockets used to advise that igniter wires be twisted together in either [series or parallel configurations](https://en.wikipedia.org/wiki/Series_and_parallel_circuits). Each has its advantages: with a series connection, any burnt igniter will show an open circuit upon arming, while with a parallel connection, the launch controller can use the same voltage as always, but supply more current to ignite multiple motors at once. Today, most clusters are wired in parallel, and the rocketeer must ensure that ample current is available for launch.
|
||||
|
||||
Some cluster igniter wiring schemes use a **buss bar** - a short length of regular conductive wire, typically non-insulated, for ease of connecting to it as needed - as a way of bridging what can be complex connections in a tight space, into an easier connection plan. For example, you can twist one end of each igniter together in a bundle, and the other end of each to the buss bar. The launch micro-clips then connect one to the bundle, and the other to the buss bar, for a parallel connection.
|
||||
|
||||
A convenient tool for igniting a cluster is a **cluster whip** - a set of wires and micro-clips that allows the single pair of clips at the launch pad to be easily broken into multiple sets of clips, to attach to multiple igniters, and providing a parallel connection. The cluster whip connects to the igniters, and the launch controller's micro-clips connect to conductors on the cluster whip.
|
||||
|
||||
Igniting Clustered APCP motors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
APCP (*Ammonium Perchlorate Composite Propellant*) motors typical of Aerotech, Cesaroni, and Loki, are slower to ignite than Black Powder motors (typical Estes motors). They may unpredictably "chuff", sit quiet for a moment and then ignite, or even "spit" the igniter out. Because of this difference, and the unpredictability of APCP motor ignition, it's more than a little likely that clustered APCP motors won't ignite simultaneously, if at all. When designing for an APCP cluster (if you decide to roll these dice...), take into account what will happen to the rocket if not all motors ignite before it pulls away from the pad. The safety of observers, and of your airframe hang in the balance.
|
||||
|
||||
Using Clustering for Body Tubes With, or Without Motors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It's possible to create imaginative designs, or mimic scale rockets of yesteryear by using OpenRocket's clustering capability. One limitation of doing so is that regular **Body tube** components have no Cluster tab. To add Clustered tubes (which are, by OpenRocket's definition always **Inner Tubes**) using OpenRocket's clustering features, you must first have a regular **Body tube**.
|
||||
|
||||
You can use your regular **Body tube** as strapping around your clustered tubes, as a **Nose cone** mount, as an eject gas manifold, or even create a "Vestigial" body tube. To do this, add a regular **Body tube** then set its length to something like .0001 cm. The **Body tube** will be in the hierarchy and can have **Inner tubes**, but will barely be seen in the renderings.
|
||||
|
||||
There are some limitations, as **Inner tubes** are not meant to be used in this way. They can't take a **Nose cone** nor some other components. They won't affect aerodynamics, even if you're trying to make them into tube-fin-like things. And whether as a unit or as a **Split cluster**, you can't convert **Inner tubes** to **Body tubes**.
|
||||
|
||||
Conventional Staging
|
||||
--------------------
|
||||
|
||||
A "closed-hull" design with a separating airframe in which finned-stages holding motors are stacked up, and lower stages holding burned-out casings separate under pressure as upper stages ignite. Conventional staging is inherently limited to three stages because of the "Pisa Effect" which results in an increasing arcing trajectory with each stage.
|
||||
|
||||
In designing multi-staged rockets, it's important to realize that the center of mass will tend to start well toward the rear of the rocket, based on the booster stage(s) weighted with the loaded motors. As booster motors are spent and the spent stage(s) ejected, the center of mass will tend to move forward. Careful design ensures that the center of mass remains forward of the center of pressure throughout the flight. Weighting and weight redistribution can move the center of mass forward, while larger fin area tends to move the center of pressure aft. Ensure at least 1.0 airframe caliber of separation between the (forward) center of mass and (aft) center of pressure. This is a rule of thumb, not a hard-and-fast stability solution.
|
||||
|
||||
Rack Staging
|
||||
------------
|
||||
|
||||
An "open-hull" design with a non-separating airframe in which motors are staked up, end-to-end, in a frame, and only the burned-out casings are ejected under pressure as higher stages ignite, stage-after-stage. So long as high average impulse lower stage motors are used to ensure adequate initial velocities, rack staging is not inherently limited because this design overcomes the "Pisa Effect."
|
||||
|
||||
Here's a **[2007 video demonstrating rack staging](https://sites.google.com/site/theskydartteam/projects/model-rocketry/rack-rocket-design)**.
|
||||
|
||||
The BPS Aerospace thrust-vectoring design uses this approach to move a new motor into position for a landing burn.
|
||||
|
||||
Regulatory Concerns
|
||||
====================
|
||||
|
||||
Rocketry is subject to regulation by federal, state, and local governments, and most of the regulations that rocketeers must follow are promulgated by the National Fire Protection Association (NFPA) and the Federal Aviation Administration (FAA). The NFPA divides rockets into two major classifications, model rockets (NFPA § 1122) and high power rockets (NFPA § 1127), the difference primarily being weight and power, as follows:
|
||||
|
||||
- **Model Rocket**. A rocket vehicle that weighs no more than 1500 g (53 oz) with motors installed, is propelled by one or more model rocket motors having an installed total impulse of no more than 320 N-sec (71.9 lb-sec), and contains no more than a total of 125 g (4.4 oz) of propellant weight. (NFPA § 1122, subd. 3.3.7.2.)
|
||||
- **High Power Rocket**. A rocket vehicle that weighs more than 1500 g (53 oz) with motors installed and is either propelled by one or more high power rocket motors or by a combination of model rocket motors having an installed total impulse of more than 320 N-sec (71.9 lb-sec). (NFPA §1127, subd. 3.3.13.1.)
|
||||
|
||||
Within the high power rocket classification, a subclassification for "complex" rockets is defined as a high power rocket that is multi-staged or propelled by a cluster of two or more rocket motors. (NFPA §1127, subd. 3.3.13.1.1.) And, a high power rocket launched with an installed total impulse greater than 2,560 N-sec (576 lb-sec) must have an electronically actuated recovery system. (NFPA §1127, subd. 4.10.2.)
|
||||
|
||||
National Association of Rocketry
|
||||
================================
|
||||
|
||||
National Association of Rocketry pursuits the goal of safe, fun and educative sport rocketry. It is the oldest and largest sport rocketry organization in the world. Visit dedicated [Wiki page](http://en.wikipedia.org/wiki/National_Association_of_Rocketry) or [NAR official website](http://www.nar.org/) for more information.
|
||||
|
||||
The major work of the NAR includes, but not limited to:
|
||||
|
||||
- Certification of Rocketry-Related products and establishment of safety codes
|
||||
|
||||
The NAR is a recognized authority for safety certification of consumer rocket motors and user certification of high- power rocket fliers in the U.S. It plays a major role in establishment of safety codes for the hobby used and accepted by manufacturers and public safety officials nationwide.
|
||||
|
||||
- Certification of experienced rocketeers
|
||||
|
||||
NAR issues three levels of High Power Rocketry (HPR) certificates, Level 1 (L1) through Level 3 (L3). Certificates are necessary to purchase powerful rocket motor components.
|
||||
|
||||
- Communication with public officials
|
||||
|
||||
The NAR helps in communication with local public safety officials, and government regulatory agencies such as the Department of Transportation, Federal Aviation Administration, Bureau of Alcohol Tobacco Firearms and Explosives, and Consumer Product Safety Commission.
|
||||
|
||||
- Other work
|
||||
|
||||
The NAR publishes the bimonthly color magazine Sport Rocketry (sent to each member and selected libraries and newsstands around the nation). The NAR provides a wide range of other services to its members, including: education programs; national and local competitions; grants to teachers and scholarships for student members; flight performance record recognition; liability insurance; and publication of technical literature.
|
||||
|
||||
Tripoli Rocketry Association
|
||||
=============================
|
||||
|
||||
<<INSERTION POINT>>
|
||||
|
@ -9,6 +9,8 @@ In this section we'll take a quick look at running a basic **Flight Simulation**
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Why simulate?
|
||||
=============
|
||||
|
||||
@ -45,7 +47,7 @@ and it includes the list of simulations pictured.
|
||||
The *Flight Simulations* window.
|
||||
|
||||
In the Flight Simulations window, you'll see the simulations listed, initially in Name order. Note that the second column
|
||||
is "Configuration" - the name of the configuration used in the sim, usually named for the rocket motor used in that
|
||||
is **Configuration** - the name of the configuration used in the sim, usually named for the rocket motor used in that
|
||||
configuration. The remaining values in the simulation's row are calculated by "running" the simulation. You can run
|
||||
one simulation by selecting a sim and clicking the :guilabel:`Run simulations` button:
|
||||
|
||||
@ -90,10 +92,10 @@ the tube as the chute deploys while the rocket continues to move rapidly forward
|
||||
|
||||
OpenRocket can detect several conditions which will mark a simulation as non-working. For example:
|
||||
|
||||
- Too slow off launch rod - unstable launch
|
||||
- Too short a delay - early deploy of chute, zipper, damage or separation likely
|
||||
- Too long a delay - late deploy of chute, zipper, damage, separation or hard ground-hit likely
|
||||
- Ground-hit velocity too high - damage, and potential danger to ground personnel
|
||||
- **Too slow off launch rod** - unstable launch
|
||||
- **Too short a delay** - early deploy of chute, zipper, damage or separation likely
|
||||
- **Too long a delay** - late deploy of chute, zipper, damage, separation or hard ground-hit likely
|
||||
- **Ground-hit velocity too high** - damage, and potential danger to ground personnel
|
||||
|
||||
These are common failure conditions, but are not intended to be an exhaustive list.
|
||||
|
||||
@ -116,20 +118,20 @@ Below, you see the **Motors & Configuration** tab for *A Simple Model Rocket*, j
|
||||
|
||||
Starting a new configuration.
|
||||
|
||||
From here, you can choose to **Select motor**, **Remove motor**, **Select ignition**, or **Reset ignition**.
|
||||
From here, you can choose to :guilabel:`Select motor`, :guilabel:`Remove motor`, :guilabel:`Select ignition`, or :guilabel:`Reset ignition`.
|
||||
|
||||
Notice that in the **Motor mounts** section of the **Motors & Configuration** panel, you can see that the **Inner Tube**
|
||||
is selected as the single motor mount tube.
|
||||
|
||||
More complex models with more motor mount tubes offer you the chance to fly with multiple motors in *Clusters* and *Airstarts*.
|
||||
The example model rockets in the **File** menu illustrate these multiple motor configurations. To learn more about how
|
||||
The example model rockets in the :menuselection:`File` menu illustrate these multiple motor configurations. To learn more about how
|
||||
multiple motors are handled, we suggest you load one of these example models and inspect the simulation and motor mount
|
||||
tube settings.
|
||||
|
||||
Select motor
|
||||
------------
|
||||
|
||||
Clicking **Select motor** brings up the **Motor Selection** panel, as shown below.
|
||||
Clicking :guilabel:`Select motor` brings up the **Motor Selection** panel, as shown below.
|
||||
|
||||
.. figure:: /img/user_guide/basic_flight_simulation/SelectAnyMotor.png
|
||||
:width: 85%
|
||||
@ -142,25 +144,25 @@ Clicking **Select motor** brings up the **Motor Selection** panel, as shown belo
|
||||
From this panel, you can select from many different motors, from many different manufacturers. There are a BUNCH of
|
||||
motors listed, but don't worry: the gadgets on this panel can help make your selection much easier.
|
||||
|
||||
Ignore **Ejection charge delay** for now. It is one of the most important settings on the page, but we'll come back to it.
|
||||
Ignore :guilabel:`Ejection charge delay` for now. It is one of the most important settings on the page, but we'll come back to it.
|
||||
|
||||
On the left, we see a list of the motors available to OpenRocket, given the filter settings on this page. The list can be
|
||||
sorted by any column, by clicking the column headers.
|
||||
|
||||
Below the list of motors is a **Search** box, which allows you to do a free-text search against the current list of motors.
|
||||
Below the list of motors is a :guilabel:`Search` box, which allows you to do a free-text search against the current list of motors.
|
||||
|
||||
On the right, the **Hide motors already used in the mount** checkbox will help you avoid creating multiple simulations
|
||||
On the right, the :guilabel:`Hide motors already used in the mount` checkbox will help you avoid creating multiple simulations
|
||||
for the same motor. One is usually enough.
|
||||
|
||||
In the **Manufacturer** section, you can filter to show only motors from particular manufacturers. This is especially
|
||||
In the :guilabel:`Manufacturer` section, you can filter to show only motors from particular manufacturers. This is especially
|
||||
important if you're using reloadable rocket motors: if you want to fly, for example, an AeroTech reloadable motor, only
|
||||
AeroTech reloads will be of use to you in this chart.
|
||||
|
||||
The **Total Impulse** selector lets you limit the list to the range of motors you want to see. No point in listing
|
||||
The :guilabel:`Total Impulse` selector lets you limit the list to the range of motors you want to see. No point in listing
|
||||
E- through O-impulse motors for *A simple model rocket*: they won't fit (and most of them would tear the rocket to
|
||||
shreds if they did).
|
||||
|
||||
The **Motor Dimensions** gadgets let you further filter the list to only motors that have the desired mechanical fit in
|
||||
The :guilabel:`Motor Dimensions` gadgets let you further filter the list to only motors that have the desired mechanical fit in
|
||||
your rocket. There's no point in trying to fit a motor that is larger diameter than your motor mount tube, though it's
|
||||
quite common to search for motors that are *smaller* than the maxim motor diameter for a given rocket, and use an adaptor
|
||||
to bring the motor up to size for the right mechanical fit.
|
||||
@ -172,11 +174,11 @@ select any of your configurations to see the effect on weight and stability.
|
||||
Ejection charge delay
|
||||
---------------------
|
||||
|
||||
Finally, to **Ejection charge delay**. One of the very common uses for OpenRocket simulations is to determine how long
|
||||
Finally, to :guilabel:`Ejection charge delay`. One of the very common uses for OpenRocket simulations is to determine how long
|
||||
a delay a motor must have for a successful flight. Too early or too late and the rocket could try to open the chute while
|
||||
it's moving quickly, causing damage. Way too late or not at all, and the rocket will crash.
|
||||
|
||||
**Ejection charge delay** will have a list of available off-the-shelf ejection charge delays for the motors in the list,
|
||||
:guilabel:`Ejection charge delay` will have a list of available off-the-shelf ejection charge delays for the motors in the list,
|
||||
but it's also a free-text field, where you can enter a particular delay in seconds.
|
||||
|
||||
.. figure:: /img/user_guide/basic_flight_simulation/OptimumDelay.png
|
||||
@ -202,7 +204,7 @@ the delay closest to what your simulation says you'll need for success.
|
||||
Show Details
|
||||
------------
|
||||
|
||||
The **Show Details** section gives you detailed information about the selected motor's thrust curve, its thrust and burn
|
||||
The :guilabel:`Show Details` section gives you detailed information about the selected motor's thrust curve, its thrust and burn
|
||||
parameters, and its certification.
|
||||
|
||||
.. figure:: /img/user_guide/basic_flight_simulation/ShowDetails.png
|
||||
@ -246,9 +248,9 @@ A digital kitchen scale can be useful to weigh each part as you create a simulat
|
||||
You'll also need to measure thicknesses and lengths. You can obtain inexpensive digital calipers which are fine for this
|
||||
measuring purpose, from suppliers like `Harbor Freight <https://www.harborfreight.com/search?q=digital%20caliper>`_.
|
||||
|
||||
Working in the **:ref:`Rocket design <rocket_design_window>`** window, measure and record the weight of each component as
|
||||
Working in the **Rocket design window**, measure and record the weight of each component as
|
||||
you model it. Try and choose the correct material to reflect the density and mass of the actual component. Often,
|
||||
creating a more-correct material (using the "Custom" option of the **Component Material** menu) is a better choice than
|
||||
creating a more-correct material (using the :guilabel:`Custom` option of the **Component Material** menu) is a better choice than
|
||||
using weight overrides, because the weight override may not reflect the correct center of mass of the overridden material.
|
||||
|
||||
Include every component the actual rocket uses, except for the motor: motors are chosen in the
|
||||
|
@ -19,6 +19,8 @@ Then we'll build a rocket from scratch to see how it’s done.
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Component Configuration Window
|
||||
==============================
|
||||
|
||||
|
151
docs/source/user_guide/custom_expressions.rst
Normal file
@ -0,0 +1,151 @@
|
||||
******************
|
||||
Custom Expressions
|
||||
******************
|
||||
|
||||
Since OpenRocket 12.09, you are not limited to using just the built-in simulation variables in your plots and
|
||||
analysis. With the custom expression feature, you can write expressions to calculate other values of interest during the
|
||||
simulation. These can then be plotted or exported just like the built-in variables.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
Custom expressions are added to your rocket document from the 'Analyze' menu under custom expressions. This will open a
|
||||
window showing all your custom expressions.
|
||||
|
||||
.. figure:: /img/user_guide/custom_expressions/custom_expressions.png
|
||||
:align: center
|
||||
:width: 55%
|
||||
:figclass: or-image-border
|
||||
:alt: The Custom Expressions window.
|
||||
|
||||
The Custom Expressions window.
|
||||
|
||||
Initially, there will be no custom expressions, so you will need to add one using the *New expression* button in the
|
||||
lower right. This opens the expression builder window. You can also import expressions from another .ork file.
|
||||
|
||||
Building expressions
|
||||
====================
|
||||
|
||||
.. figure:: /img/user_guide/custom_expressions/expression_builder.png
|
||||
:align: center
|
||||
:width: 45%
|
||||
:figclass: or-image-border
|
||||
:alt: The Expression Builder window.
|
||||
|
||||
The Expression Builder window.
|
||||
|
||||
You must specify a name for the expression, a short symbol, the units of the resulting value, and of course the expression
|
||||
itself. After you enter a valid value in each of the fields the adjacent indicator will change from red to green. Only
|
||||
when all indicators are green will you be able to add or update the expression.
|
||||
|
||||
- The :guilabel:`Name` field can be arbitrary; it only must have not been used before.
|
||||
- The :guilabel:`Symbol` field is intended for a short (locale-independent) symbol representing the value. It must not have been
|
||||
used before, contain no numbers, whitespaces, or special characters such as brackets or operators.
|
||||
- There are no restrictions on the :guilabel:`Units`; it can even be empty for dimensionless quantities. However, if you enter a
|
||||
standard SI unit then you will be able to automatically convert the units when plotting or exporting. The available
|
||||
SI units are: m, m^2, m/s, kg, kg m^2, kg m^3, N, Ns, s, Pa, V, A, J, W, kg m/s, Hz, K. They must match exactly.
|
||||
- The :guilabel:`Expression` must only contain valid symbols, operators, and numbers and must make sense mathematically.
|
||||
For convenience, the adjacent indicator updates on-the-fly.
|
||||
- It is possible to nest custom expressions, i.e., you can use the symbol defined for a custom expression in another
|
||||
expression. However, you must ensure that expressions are calculated in the correct order if you do this. This can be
|
||||
done using the blue arrows in the custom expression pane to adjust the order of calculation.
|
||||
|
||||
To see a list of the available variables and their symbols, click the :guilabel:`Insert Variable` button. This will open a window
|
||||
from which you can choose a variable and insert it (at the current cursor position) in the expression box. This is
|
||||
particularly useful because you may not be able to type some of the symbols on your keyboard. The :guilabel:`Insert Operator`
|
||||
window is similar and shows all the available mathematical operators and functions.
|
||||
|
||||
Index expressions
|
||||
=================
|
||||
|
||||
The custom expressions are calculated at each time step of the simulation; however, there are some cases where it is
|
||||
useful to have access to earlier values of a given variable. This is possible using **index expressions**. These use a
|
||||
square bracket syntax to specify the time (in seconds) for the variable you want. For example, the expression:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
m / m[0]
|
||||
|
||||
would give the ratio of the current mass to the launch mass at time 0. Similarly,
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
m - m[t-1]
|
||||
|
||||
would give you the change in mass over the last second.
|
||||
|
||||
You can specify any valid sub-expression inside the square brackets; the only restriction is that you can't nest another
|
||||
index/range expression inside the square brackets.
|
||||
|
||||
When indexed expressions are calculated, interpolation is used to get the value exactly at the specified time, independent
|
||||
of the time steps of the simulation.
|
||||
|
||||
If you specify a time smaller than 0 or greater than t then it will be clipped to 0 or t respectively. You can't access
|
||||
data that has not been calculated yet.
|
||||
|
||||
Range expressions
|
||||
=================
|
||||
|
||||
It is sometimes useful to have access to a range of values of a particular variable rather than just one point.
|
||||
OpenRocket includes a number of useful operators for calculating statistics and other properties of ranges. These
|
||||
operators can be identified in the operator selection box by the *\[\:\]* which will already have been filled out in place
|
||||
of one or more of the parameters.
|
||||
|
||||
Range expressions are defined with a square bracket syntax similar to index expressions, but with a ':' used to separate
|
||||
the lower and upper bounds of a range. For example, suppose we had an accelerometer on our rocket which (as many do)
|
||||
includes some low-pass filtering on the output. This can be modeled as a moving average and defined with a custom
|
||||
expression such as:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
mean(At[t-0.5:t])
|
||||
|
||||
which will calculate a moving mean for the variable At (total acceleration) over the last 0.5 seconds of data.
|
||||
|
||||
As with index expressions, the upper and lower bounds can be any valid expression. If omitted, the upper bound will
|
||||
default to t and the lower bound to 0, so the above expression can also be written
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
mean(At[t-0.5:])
|
||||
|
||||
In this particular case, we might want to make the expression more realistic by clipping accelerations above a given
|
||||
threshold and perhaps returning the actual voltage from the sensor, for example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
0.2 * uclip( mean(At[t-.5:]), 10 )
|
||||
|
||||
Note that when range expressions are calculated the data is generated by interpolation over the specified range with a
|
||||
fixed time step equal to the default time step set in your simulation options. This is independent of the current time step
|
||||
*dt* used by the simulation engine. When generated, range expressions include the start time and step information.
|
||||
This facilitates easy integration or optimization with functions such as *trapz([:])* for trapezoidal integration or
|
||||
*tnear([:],x)* for finding the time value when a variable is nearest a specified value.
|
||||
|
||||
For a complete list of all the operators available see the operator selection list when making a new expression.
|
||||
|
||||
Troubleshooting
|
||||
===============
|
||||
|
||||
While OpenRocket makes a reasonable attempt to check your expression as you enter it, it is still possible to enter
|
||||
something invalid or that can't be calculated for some reason. In this case you will simply end up with no data available
|
||||
to plot after running the simulation.
|
||||
|
||||
If you can't figure out why your expression is not generating any data or can't be accepted by the expression builder
|
||||
then you might find some useful information in the error log. This can be accessed from the help -> debug log menu. Any
|
||||
relevant messages are probably under the 'USER' category.
|
||||
|
||||
It should not be possible to cause a crash with an invalid expression. If you manage to, please report the bug and
|
||||
include your expression.
|
||||
|
||||
Custom expressions are interpreted during the simulation and are necessarily much slower than "native" datatypes.
|
||||
For a few simple expressions you probably won't notice much speed difference but it can become particularly significant
|
||||
if you have range expressions. If speed is an issue for you then you might want to consider implementing your expression
|
||||
as a `simulation listener <Simulation_Listeners>`_.
|
330
docs/source/user_guide/overrides_and_surface_finish.rst
Normal file
@ -0,0 +1,330 @@
|
||||
****************************
|
||||
Overrides and Surface Finish
|
||||
****************************
|
||||
|
||||
This page explains how to use overrides and surface finish settings to create more accurate OpenRocket simulations.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Using Overrides and Surface Finish to Create More Accurate OpenRocket Simulations
|
||||
=================================================================================
|
||||
|
||||
As you develop your design, OpenRocket estimates the rocket's stability and performance characteristics based on entered
|
||||
and known information about the components you choose. As you accumulate parts, and build and test your rocket, you will
|
||||
obtain more accurate information than what OpenRocket estimated. With this knowledge, you can override the initial
|
||||
estimates and create more accurate flight simulations.
|
||||
|
||||
On this page, how OpenRocket looks at the different overrides will be explained in more detail, and practical examples
|
||||
of their use will be given.
|
||||
|
||||
Overrides
|
||||
---------
|
||||
|
||||
OpenRocket allows you to override three values that are determinative of a rocket’s flight characteristics: mass, center
|
||||
of gravity (CG), and coefficient of drag (C\ :sub:`D`). All three of these values can be overridden at the stage level,
|
||||
the component group level, or the single component level. In addition, while not being an override in its own right,
|
||||
OpenRocket allows you to adjust the surface roughness of components so that drag estimates more accurately reflect
|
||||
actual flight data.
|
||||
|
||||
Override Mass
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The database of parts included with OpenRocket has estimates for component masses. These estimates come from a variety
|
||||
of sources, ranging from data provided by the manufacturer and measured values to calculations based on the volume of
|
||||
the part and the "standard" density of the material it is made from. The accuracy of these sources varies, but nothing
|
||||
is more accurate than putting the actual part on a scale and weighing it. Once a part's measured mass is known, the mass
|
||||
override can be used to change the mass value, more closely reflecting the part's mass, and thereby the rocket's actual
|
||||
mass.
|
||||
|
||||
Override Center of Gravity
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
OpenRocket also estimates each component's center of gravity based on its materials and geometry, and calculates the
|
||||
overall center of gravity of each stage, and the entire rocket based on that. However, this really can't account for
|
||||
the weight of things like glue and paint, which can be significant and can move the center of gravity forward or back.
|
||||
Once you've got some components assembled, you can measure the CG (using any of the time-honored methods, like hanging
|
||||
from a string or balancing on a knife edge) and override this, too.
|
||||
|
||||
Override Coefficient of Drag
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The drag on a rocket in flight is a function of the rocket's velocity, the density of the atmosphere, the frontal area
|
||||
of the rocket, and a number called the coefficient of drag. This, in turn, is a result of the airflow over the rocket,
|
||||
and is estimated based on the rocket's geometry and surface finish. Once you've actually flown the rocket and compared
|
||||
your simulation to the actual flight, you can adjust the rocket's coefficient of drag to better match the flight data.
|
||||
|
||||
One caution, the coefficient of drag does not remain constant through the flight, especially if the rocket gets near the
|
||||
speed of sound. At low speeds the friction on the rocket's body dominates the coefficient of drag, but as the speed
|
||||
increases the effect of the pressure drag (the drag caused by the pressure of the front of the rocket hitting air) and
|
||||
the base drag (caused by the low pressure area left behind the rocket) becomes progressively more significant. Adjusting
|
||||
the coefficient of drag based on a flight with a small motor, and using this result to estimate behavior with a larger
|
||||
motor can give misleading results. How to use drag coefficient overrides to "adjust" a calculated drag coefficient will
|
||||
be discussed later.
|
||||
|
||||
Override for All Subcomponents
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
OpenRocket designs are structured as a tree: each component (except the rocket itself) has a parent component and may
|
||||
have children (subcomponents). For instance, a single stage rocket will have that single stage as the child of the rocket,
|
||||
and the stage will have (at least) a nose cone and a body tube as subcomponents. If fins are attached to the body tube,
|
||||
the fin set is a subcomponent of the body tube. When applying overrides to a component, you can specify whether to apply
|
||||
the override to all of its subcomponents as well. If you don't override the subcomponents, then the override applied to
|
||||
the parent component is combined with that of all subcomponents. For instance, suppose a body tube has a calculated mass
|
||||
of 100 grams and its fins have a calculated mass of 50 grams, the combination of body tube and fin set will have a mass
|
||||
of 150 grams. If you override the body tube mass, set it to 110 grams, and don't override the subcomponents, the total
|
||||
mass is now 160 grams.
|
||||
|
||||
If you do override the subcomponents, then the set mass of the parent replaces the mass of the entire subtree. So, using
|
||||
the same body tube and fin set as before, if you set the mass override of the body tube to 170 grams, and override the
|
||||
subcomponents, the total mass is 170 grams; the fins contribute no additional mass to the assembly.
|
||||
|
||||
But, why would you want to do this? Ultimately, the goal is to match the simulated mass to the measured mass after the
|
||||
rocket is finished, taking into account such things as adhesives and any exterior finish (paint and decals). In the case
|
||||
described above, the mass override is for the entire assembly -- the idea is that if you actually glue the fins to the
|
||||
body tube and weigh the result at 170 grams, that's what you want the finished mass of the assembly to be.
|
||||
|
||||
Using Overrides to Produce a More Accurate Simulation
|
||||
-----------------------------------------------------
|
||||
|
||||
Let's look at how you can apply overrides at different points in the design, construction, and simulation of the rocket
|
||||
to improve the accuracy of your simulations.
|
||||
|
||||
When Designing Your Rocket
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You start designing your rocket by selecting different components, parts that have associated mass values and calculated
|
||||
values for the center of gravity and coefficient of drag. As you add parts, OpenRocket continuously updates to combined
|
||||
values, calculating an estimated mass, center of gravity, and coefficient of drag for the entire rocket. Then, based on
|
||||
your mass and performance goals, you select a motor. When you have, it is time to make sure the center of gravity is
|
||||
forward of the center of pressure by a comfortable stability margin; assuming it is, you can order your parts and start
|
||||
putting the rocket together.
|
||||
|
||||
When You Have Your Parts
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once you have your parts -- the nose cone, body tube, fin stock, and whatever recovery devices and other hardware you're
|
||||
using -- you can weigh each component separately. You're likely to find that the parts weigh something close to the
|
||||
calculated values, but are not exactly right. So, this (the individual part) is the lowest level on which you can
|
||||
override a mass. After overriding the mass of each part, you can check again to be certain that the center of gravity
|
||||
is still forward of the center of pressure by a comfortable stability margin, and modify your design as needed.
|
||||
|
||||
As You Build Your Rocket
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When assembling your rocket, as you complete subassemblies, you can weigh these subassemblies and measure their centers
|
||||
of gravity, applying mass and center of gravity overrides at the second (subassembly) level. When applying an override
|
||||
to a subassembly, you want to check the "Override for all Subcomponents" so that you don't count a subcomponent within
|
||||
the assembly twice.
|
||||
|
||||
Finally, when your rocket is complete, you can again weigh and measure the center of gravity of the entire rocket, and
|
||||
apply these overrides at the highest (stage) level. Once again, at this level you'll want to override subcomponents.
|
||||
|
||||
**Note: you should perform this override on every rocket you ever create. This gives the most accurate possible starting
|
||||
point for your simulations.**
|
||||
|
||||
After Your First Test Flight
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once you've flown your rocket for the first time, you can compare your simulations to your actual flight data. Since
|
||||
each of your simulations was based on overridden measured mass and center of gravity values, the only thing you need to
|
||||
adjust at this point is drag. You can take two approaches to this, you can adjust the friction drag by changing the
|
||||
rocket's surface finish, or you can directly modify the drag coefficient. The process is much the same in both cases.
|
||||
|
||||
To change the surface finish, you select external components (parts of the rocket's actual airframe) and simply select
|
||||
a different surface finish. Then, rerun the simulation again, and compare the new difference between the actual flight
|
||||
results and your new simulation; you continue to adjust the surface finish until you are satisfied that the simulation
|
||||
results are as close as possible to the actual flight data. Even though only the airframe surface matters, for the first
|
||||
few adjustments, it is easier to select a new component finish on any part and then simply click the "Apply to All Components"
|
||||
button. After you have bracketed your desired simulation result, you can fine-tune the simulation by adjusting the surface
|
||||
finish for individual components.
|
||||
|
||||
To directly adjust the drag coefficient, you apply a drag coefficient override to the entire stage. In this case you
|
||||
don't want to override the subcomponents; what you're doing is applying a constant offset to the drag coefficient
|
||||
being calculated over the course of the flight.
|
||||
|
||||
After applying these modifications, you will have a more accurate simulation for future flights with different motors.
|
||||
|
||||
How and Why to Use Mass and Center of Gravity Overrides
|
||||
=======================================================
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
The ‘’Stage’‘, ‘’Boosters’‘, and ‘’Pods’‘ assembly components feature mass and center of gravity override options that
|
||||
may be used to adjust the rocket’s margin of stability. Prior to the release of OpenRocket 22.02 Beta 5, the use of these
|
||||
options overrode the mass and center of gravity of **all** of the assembly subcomponents, limiting the use of these
|
||||
options to matching the rocket’s finished mass and center of gravity.
|
||||
|
||||
Beginning with the release of OpenRocket 22.02 Beta 5, when using these options, you may choose not to override the mass
|
||||
and center of gravity of the assembly subcomponents, choosing instead to add to or subtract from the values calculated
|
||||
by OpenRocket. So, why is this an important change?
|
||||
|
||||
.. _margin_of_stability:
|
||||
|
||||
Margin of Stability
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The recommended **stability margin for subsonic flights is not less than 1.0 caliber**, and **not less than 2.0 calibers
|
||||
for transonic and supersonic flights**. However, the rocket’s stability margin changes during flight; the rocket can have
|
||||
momentary marginal stability right off the launch rail with wind, or at high angles of attack at low velocity going
|
||||
through apogee, but may otherwise be unstable during flight.
|
||||
|
||||
Effect of Rotational Inertia
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The cause of instability during flight is often rooted in the rocket’s rotational inertia (moment of inertia), how the
|
||||
rocket’s mass is distribution about the axis (center of gravity), with larger moments requiring more torque to change
|
||||
the rocket’s rate of rotation. When subcomponent mass and center of gravity values are overridden, the rocket’s rotational
|
||||
inertia is changed, potentially causing the rocket to simulate as stable when it is not, or as unstable when it is, at
|
||||
less than or near recommended stability margins.
|
||||
|
||||
Benefit of Not Overriding Subassembly Subcomponents
|
||||
---------------------------------------------------
|
||||
|
||||
The rocket’s center of gravity can be viewed as the balancing point between the nose cone tip and the end of the motor
|
||||
nozzle. If a large, heavy motor is used, then weight at the rocket’s tip is needed to balance that weight. And, this
|
||||
creates a large rotational inertia, which may be significantly changed when the user overrides the subcomponent mass and
|
||||
center of gravity values. Now, you can add mass at a specific location within the assembly component, without changing
|
||||
the mass and center of gravity values of subcomponents.
|
||||
|
||||
How the Mass and Center of Gravity Overrides Work
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you select "override for all subcomponents", your value is set as an aggregate Mass or Center of Gravity value. If
|
||||
you don't select it, your set value is added to the calculated value of the Mass or Center of Gravity. The Coefficient of
|
||||
Drag override work in the same way.
|
||||
|
||||
Matching Measured Mass and Center of Gravity
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In other words, it is now possible to reduce the effect that matching measured mass and center of gravity has on the
|
||||
rocket’s calculated rotational inertia. The user simply checks the assembly component’s mass and center of gravity
|
||||
overrides, entering the difference between the measured and calculated values, leaving the override subcomponents box
|
||||
unchecked. This method is less likely to have a material effect on the rocket’s rotational inertia than overriding all
|
||||
the subcomponent values.
|
||||
|
||||
Adjustable Weight Systems
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Using the assembly component’s mass and center of gravity overrides in this way, you can mimic adjustable weight systems
|
||||
to compensate for significant changes in motor size and mass. The number of steps involved depends on the precision you
|
||||
want achieve.
|
||||
|
||||
The approaches described below assume that you have a completed design that you will be making changes to; The steps
|
||||
below describe how to make the changes to the "A simple model rocket" example include with OpenRocket.
|
||||
|
||||
Simplified Approach
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The simplified approach has three basic steps.
|
||||
|
||||
The first step is to place a *Mass Component* inside the airframe, to match the rocket’s **flight ready** measured weight
|
||||
and center of gravity (without a motor); it doesn't matter which component it is put inside of because you should position
|
||||
it relative to the "Tip of the nose cone", entering your measured distance from the rocket's nose cone tip to the rocket's
|
||||
actual center of gravity.
|
||||
|
||||
The second step, going to the *Stage configuration* pane, is to enter the distance from the tip of the nose cone to the
|
||||
center of your adjustable weight as the *Override center of gravity* distance.
|
||||
|
||||
The third step is really two companion steps, you select your preferred motor configuration, and, on the
|
||||
*Stage configuration* pane, you adjust the mass override value until you have a comfortable margin of stability between
|
||||
the center of gravity and center of pressure (see, :ref:`Margin of Stability <margin_of_stability>`). Then, last of all, **don't forget to actually
|
||||
add that amount of weight to your rocket's adjustable weight system**.
|
||||
|
||||
After that, before you head out to the range, actually install the motor (without the igniter) and verify the margin of
|
||||
stability; it's always nice to put markers on the rocket, blue for the center of gravity and red for the center of pressure.
|
||||
|
||||
Precision Approach
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The highest level of precision requires that the mass overrides be used for **each component** and **each subassembly**,
|
||||
and, finally, at the **stage** level. To achieve this precision, there are a few additional steps:
|
||||
|
||||
1. Lay out, weigh, and enter the mass override for each of the parts.
|
||||
2. Using the component tree as your reference, identify each component that has one or more subcomponents under it.
|
||||
These components will be referred to as parents and the component and its subcomponents, together, will be called a
|
||||
subassembly; oft times there are nested subcomponents and each component with a subcomponent is a parent.
|
||||
3. While building the rocket, each time a subassembly is completed, weigh that subassembly and enter the mass override
|
||||
value on the parent's configuration override tab, checking the "Override mass and CG of all subcomponents" box. This will
|
||||
take into account the additional mass of adhesives, fasteners, and the like.
|
||||
|
||||
From here, follow the `Simplified Approach`_ steps, above, which describes how to make the remaining changes.
|
||||
|
||||
As stated before, before you head out to the range, **actually install the motor (without the igniter) and *verify the
|
||||
margin of stability***; again, it's always nice to put markers on the rocket, blue for the center of gravity and red for
|
||||
the center of pressure.
|
||||
|
||||
How and Why to Use Surface Finish Settings and Coefficient of Drag (C\ :sub:`D`) Overrides
|
||||
==========================================================================================
|
||||
|
||||
When you have finished your rocket, and adjusted the mass and center of gravity overrides as described above, there are
|
||||
two remaining factors affecting flight performance that can be adjusted, the rocket's coefficient of drag and surface
|
||||
finish (roughness). After you have flown your rocket and collected flight data (using an altimeter or other device),
|
||||
you can compare the actual flight results to the OpenRocket simulation projections and make changes to the rocket's
|
||||
(C\ :sub:`D`) or surface finish to bring the simulated results in line with the actual collected fight data.
|
||||
|
||||
The first step is usually bracketing the desire drag coefficient by changing the rocket's *Surface Finish*, and the
|
||||
second is fine tuning the (C\ :sub:`D`) with the *Stage* level override. You can adjust the rocket's (C\ :sub:`D`) by
|
||||
changing its surface roughness or by overriding its overall (C\ :sub:`D`), or a combination of both, depending upon the
|
||||
precision you desire.
|
||||
|
||||
Using Surface Finish (Roughness) Settings
|
||||
-----------------------------------------
|
||||
|
||||
The surface finish that you use for your rocket affects how air flows over the airframe (the smoother the surface, the
|
||||
less the resistance; the rougher the surface, the greater the resistance). And, another word for this resistance is drag.
|
||||
So, an adjustment to surface roughness changes the rocket's (C\ :sub:`D`).
|
||||
|
||||
As with other component specific characteristics, each component has its own *Surface Finish* setting, although you can
|
||||
change the *Surface Finish* of every component by left-clicking the *Set for all* button on any *Appearance* tab. This
|
||||
is similar to the override subcomponents feature, but only changes the components that exist at the time it us used;
|
||||
parts added after using the *Set for all* feature will have the default roughness. OpenRocket allows you to select one
|
||||
of five roughness settings, *Rough*, *Unfinished*, *Regular paint*, *Smooth paint*, and *Polished*, each with a
|
||||
decreasing (C\ :sub:`D`) from rough to polished.
|
||||
|
||||
Using your actual collected flight data, by making the exterior of your rocket's surface rougher or smoother, you are
|
||||
changing the rocket's overall (C\ :sub:`D`) without overriding the (C\ :sub:`D`) of any components. This method retains
|
||||
all of the component (C\ :sub:`D`) values and does not affect the simulation's ability to calculate the natural
|
||||
(C\ :sub:`D`) variations caused by changes in velocity and atmospheric density during flight.
|
||||
|
||||
When making changes using this method, a change is made to the *Surface Finish* setting, the simulation is rerun, and
|
||||
the results compared. You then repeat this until you have bracketed the comparison between the actual collected flight
|
||||
results and the simulation results. Then, out of the two bracketing simulations, set the *Surface Finish* to the setting
|
||||
used in the simulation with the lowest results. If you want even more precision, adjust the Rocket's (C\ :sub:`D`) as
|
||||
described below.
|
||||
|
||||
Using Coefficient of Drag (C\ :sub:`D`) Overrides
|
||||
-------------------------------------------------
|
||||
|
||||
How the Stage Coefficient of Drag Override Works
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you select "override for all subcomponents", your value is set as an aggregate (C\ :sub:`D`) value. If you don't
|
||||
select it, your set value is added to the calculated value. This is consistent with how the mass and CG overrides work.
|
||||
|
||||
Using the Stage Coefficient of Drag Override
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The coefficient of drag relates to a thing's resistance to airflow, and changes with velocity and the density of the
|
||||
atmosphere, especially if the rocket gets near the speed of sound. Only the rocket's exterior components that comprise
|
||||
the airframe of the rocket are exposed to the flow of air over the rocket and have a (C\ :sub:`D`) value that affects
|
||||
flight performance. And adjusting the coefficient of drag for the entire rocket based on a flight with a small motor,
|
||||
then using those results to estimate behavior with a larger motor can give misleading results. Because of this, and the
|
||||
practical impossibility for most users to measure the drag of each component, or the finished rocket for that matter,
|
||||
*overriding the (*C\ :sub:`D`*) at the component and subassembly levels is* **NOT recommended**.
|
||||
|
||||
However, armed with actual collected flight data, you can add or subtract from the rocket's overall (C\ :sub:`D`) at the
|
||||
"Stage" level by NOT overriding the (C\ :sub:`D`) of subcomponents. Practically speaking, this method retains all of the
|
||||
individual component (C\ :sub:`D`) values, but nudges the (C\ :sub:`D`) of the entire rocket just a bit more. And,
|
||||
OpenRocket uses this nudge to more closely match actual flight and simulation results, *without affecting the simulation's
|
||||
ability to calculate the natural (*C\ :sub:`D`*) variations caused by changes in velocity and atmospheric density during
|
||||
flight*.
|
||||
|
||||
When making changes using this method, a change is made to the (C\ :sub:`D`), the simulation is rerun, and the results
|
||||
compared. You then repeat this until you are satisfied with the comparison between the actual collected flight results
|
||||
and the simulation results.
|
14
docs/source/user_guide/rocket_analysis.rst
Normal file
@ -0,0 +1,14 @@
|
||||
***************
|
||||
Rocket Analysis
|
||||
***************
|
||||
|
||||
.. warning::
|
||||
|
||||
This chapter is a work in progress.
|
||||
|
||||
- *component analysis dialog*
|
||||
- *more details about the plottable variables? - pick up from previous chapter and cover the rest of the graphing/plottable variables in full.*
|
||||
- *instructions to export simulation data and use it elsewhere*
|
||||
- *print / pdf export*
|
||||
|
||||
*This chapter has some overlap with Advanced Flight Simulation, need to check the division.*
|
455
docs/source/user_guide/simulation_extensions.rst
Normal file
@ -0,0 +1,455 @@
|
||||
*********************
|
||||
Simulation Extensions
|
||||
*********************
|
||||
|
||||
By using OpenRocket's extension and listener mechanism, it's possible to modify the program itself to add features that
|
||||
are not supported by the program as distributed; some extensions that have been created already provide the ability to
|
||||
air-start a rocket, to add active roll control, and to calculate and save extra flight data.
|
||||
|
||||
This page will discuss extensions and simulations. We'll start by showing how a simulation is executed
|
||||
(so you can get a taste of what's possible), and then document the process of creating the extension.
|
||||
|
||||
.. warning::
|
||||
|
||||
Writing an extension inserts new code into the program. It is entirely possible to disrupt a simulation in a way that
|
||||
invalidates simulation results, or can even crash the program. Be careful!
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Adding an Existing Extension to a Simulation
|
||||
============================================
|
||||
|
||||
Extensions are added to a simulation through a menu in the "Simulation Options" tab.
|
||||
|
||||
1. Open a .ork file and go to the **Flight Simulations** tab.
|
||||
2. Click the **Edit simulation** button to open the **Edit simulation** dialog.
|
||||
3. Go to the **Simulation options** tab.
|
||||
4. Click the **Add extension** button.
|
||||
|
||||
This will open a menu similar to the one in the following screenshot:
|
||||
|
||||
.. figure:: /img/user_guide/simulation_extensions/Extension-menu.png
|
||||
:align: center
|
||||
:width: 35%
|
||||
:figclass: or-image-border
|
||||
:alt: Extension menu
|
||||
|
||||
Extension menu.
|
||||
|
||||
Clicking on the name of an extension will add it to the simulation; if it has a configuration dialog the dialog will be opened:
|
||||
|
||||
.. figure:: /img/user_guide/simulation_extensions/Air-start-configuration.png
|
||||
:align: center
|
||||
:width: 45%
|
||||
:figclass: or-image-border
|
||||
:alt: Air-start configuration dialog
|
||||
|
||||
Air-start configuration dialog.
|
||||
|
||||
In the case of the air-start extension, the configuration dialog allows you to set the altitude and velocity at which
|
||||
your simulation will begin. After you close the configuration dialog (if any), a new panel will be added to the
|
||||
**Simulation options** pane, showing the new extension with buttons to reconfigure it, obtain information about it, or
|
||||
remove it from the simulation:
|
||||
|
||||
.. figure:: /img/user_guide/simulation_extensions/Air-start-pane.png
|
||||
:align: center
|
||||
:width: 35%
|
||||
:figclass: or-image-border
|
||||
:alt: Air-start extension pane
|
||||
|
||||
Air-start extension pane.
|
||||
|
||||
Creating a New OpenRocket Extension
|
||||
===================================
|
||||
|
||||
The remainder of this page will describe how a new simulation extension is created.
|
||||
|
||||
Preliminary Concepts
|
||||
--------------------
|
||||
|
||||
Before we can discuss writing an extension, we need to briefly discuss some of the internals of OpenRocket. In particular,
|
||||
we need to talk about the simulation status, flight data, and simulation listeners.
|
||||
|
||||
Simulation Status
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
As a simulation proceeds, it maintains its state in a `SimulationStatus`. The `SimulationStatus` object contains
|
||||
information about the rocket's current position, orientation, velocity, and simulation state. It also contains a
|
||||
reference to a copy of the rocket design and its configuration. Any simulation listener method may modify the state of
|
||||
the rocket by changing the properties of the `SimulationStatus` object.
|
||||
|
||||
You can obtain current information regarding the state of the simulation by calling `get*()` methods. For instance, the
|
||||
rocket's current position is returned by calling `getRocketPosition()`; the rocket's position can be changed by calling
|
||||
`setRocketPosition<Coordinate position>`. All of the `get*()` and `set*()` methods can be found in
|
||||
:file:`code/src/net/sf/openrocket/simulation/SimulationStatus.java`. Note that while some information can be obtained in
|
||||
this way, it is not as complete as that found in `FlightData` and `FlightDataBranch` objects.
|
||||
|
||||
Flight Data
|
||||
~~~~~~~~~~~
|
||||
|
||||
OpenRocket refers to simulation variables as `FlightDataType`s, which are `List<Double>` objects with one list for each
|
||||
simulation variable and one element in the list for each time step. To obtain a `FlightDataType`, for example the current
|
||||
motor mass, from `flightData`, we call `flightData.get(FlightDataType.TYPE_MOTOR_MASS)`. The standard `FlightDataType`
|
||||
lists are all created in `core/src/net/sf/openrocket/simulation/FlightDataType.java`; the mechanism for creating a new
|
||||
`FlightDataType` if needed for your extension will be described later.
|
||||
|
||||
Data from the current simulation step can be obtained with e.g. `flightData.getLast(FlightDataType.TYPE_MOTOR_MASS)`.
|
||||
|
||||
The simulation data for each stage of the rocket's flight is referred to as a `FlightDataBranch`. Every simulation has
|
||||
at least one `FlightDataBranch` for its sustainer, and will have additional branches for its boosters.
|
||||
|
||||
Finally, the collection of all of the `FlightDataBranch`es and some summary data for the simulation is stored in a
|
||||
`FlightData` object.
|
||||
|
||||
Flight Conditions
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Current data regarding the aerodynamics of the flight itself are stored in a ``FlightConditions`` object. This includes
|
||||
things like the velocity, angle of attack, and roll and pitch angle and rates. It also contains a reference to the
|
||||
current ``AtmosphericConditions``.
|
||||
|
||||
Simulation Listeners
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Simulation listeners are methods that OpenRocket calls at specified points in the computation to either record
|
||||
information or modify the simulation state. These are divided into three interface classes, named ``SimulationListener``,
|
||||
``SimulationComputationListener``, and ``SimulationEventListener``.
|
||||
|
||||
All of these interfaces are implemented by the abstract class ``AbstractSimulationListener``. This class provides empty
|
||||
methods for all of the methods defined in the three interfaces, which are overridden as needed when writing a listener.
|
||||
A typical listener method (which is actually in the Air-start listener), would be:
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
public void startSimulation(SimulationStatus status) throws SimulationException {
|
||||
status.setRocketPosition(new Coordinate(0, 0, getLaunchAltitude()));
|
||||
status.setRocketVelocity(status.getRocketOrientationQuaternion().rotate(new Coordinate(0, 0, getLaunchVelocity())));
|
||||
}
|
||||
|
||||
This method is called when the simulation is first started. It obtains the desired launch altitude and velocity from its
|
||||
configuration, and inserts them into the simulation status to simulate an air-start.
|
||||
|
||||
The full set of listener methods, with documentation regarding when they are called, can be found in
|
||||
:file:`core/src/net/sf/openrocket/simulation/listeners/AbstractSimulationListener.java`.
|
||||
|
||||
The listener methods can have three return value types:
|
||||
|
||||
* The ``startSimulation()``, ``endSimulation()``, and ``postStep()`` are called at a specific point of the simulation. They are
|
||||
void methods and do not return any value.
|
||||
* The ``preStep()`` and event-related hook methods return a boolean value indicating whether the associated action should
|
||||
be taken or not. A return value of ``true`` indicates that the action should be taken as normally would be (default),
|
||||
``false`` will inhibit the action.
|
||||
* The pre- and post-computation methods may return the computed value, either as an object or a double value. The
|
||||
pre-computation methods allow pre-empting the entire computation, while the post-computation methods allow augmenting
|
||||
the computed values. These methods may return ``null`` or ``Double.NaN`` to use the original values (default), or return
|
||||
an overriding value.
|
||||
|
||||
Every listener receives a ``SimulationStatus`` (see above) object as the first argument, and may also have additional arguments.
|
||||
|
||||
Each listener method may also throw a ``SimulationException``. This is considered an error during simulation (not a bug),
|
||||
and an error dialog is displayed to the user with the exception message. The simulation data produced thus far is not
|
||||
stored in the simulation. Throwing a ``RuntimeException`` is considered a bug in the software and will result in a bug report dialog.
|
||||
|
||||
If a simulation listener wants to stop a simulation prematurely without an error condition, it needs to add a flight
|
||||
event of type ``FlightEvent.SIMULATION_END`` to the simulation event queue:
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
status.getEventQueue().add(new FlightEvent(FlightEvent.Type.SIMULATION_END, status.getSimulationTime(), null));
|
||||
|
||||
This will cause the simulation to be terminated normally.
|
||||
|
||||
Creating a New Simulation Extension
|
||||
-----------------------------------
|
||||
|
||||
Creating an extension for OpenRocket requires writing three classes:
|
||||
|
||||
* A listener, which extends ``AbstractSimulationListener``. This will be the bulk of your extension, and performs all the real work.
|
||||
* An extension, which extends ``AbstractSimulationExtension``. This inserts your listener into the simulation. Your listener
|
||||
can (and ordinarily will) be private to your extension.
|
||||
* A provider, which extends ``AbstractSimulationExtensionProvider``. This puts your extension into the menu described above.
|
||||
|
||||
In addition, if your extension will have a configuration GUI, you will need to write:
|
||||
|
||||
* A configurator, which extends ``AbstractSwingSimulationExtensionConfigurator<E>``
|
||||
|
||||
You can either create your extension outside the source tree and make sure it is in a directory that is in your Java
|
||||
classpath when OpenRocket is executed, or you can insert it in the source tree and compile it along with OpenRocket.
|
||||
Since all of OpenRocket's code is freely available, and reading the code for the existing extensions will be very helpful
|
||||
in writing your own, the easiest approach is to simply insert it in the source tree. If you select this option, a very
|
||||
logical place to put your extension is in:
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
core/src/net/sf/openrocket/simulation/extension/example/
|
||||
|
||||
This is where the extension examples provided with OpenRocket are located. Your configurator, if any, will logically go in:
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
swing/src/net/sf/openrocket/simulation/extension/example/
|
||||
|
||||
Extension Example
|
||||
-----------------
|
||||
|
||||
To make things concrete, we'll start by creating a simple example extension, to air-start a rocket from a hard-coded altitude.
|
||||
Later, we'll add a configurator to the extension so we can set the launch altitude through a GUI at runtime. This is a
|
||||
simplified version of the ``AirStart`` extension located in the OpenRocket source code tree; that class also sets a
|
||||
start velocity.
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
package net.sf.openrocket.simulation.extension.example;
|
||||
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.extension.AbstractSimulationExtension;
|
||||
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
/**
|
||||
* Simulation extension that launches a rocket from a specific altitude.
|
||||
*/
|
||||
public class AirStartExample extends AbstractSimulationExtension {
|
||||
|
||||
public void initialize(SimulationConditions conditions) throws SimulationException {
|
||||
conditions.getSimulationListenerList().add(new AirStartListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Air-Start Example";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Simple extension example for air-start";
|
||||
}
|
||||
|
||||
private class AirStartListener extends AbstractSimulationListener {
|
||||
|
||||
@Override
|
||||
public void startSimulation(SimulationStatus status) throws SimulationException {
|
||||
status.setRocketPosition(new Coordinate(0, 0, 1000.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
There are several important features in this example:
|
||||
|
||||
* The ``initialize()`` method in lines 14-16, which adds the listener to the simulation's ``List`` of listeners. This is the
|
||||
only method that is required to be defined in your extension.
|
||||
* The ``getName()`` method in lines 19-21, which provides the extension's name. A default ``getName()`` is provided by
|
||||
``AbstractSimulationExtension``, which simply uses the classname (so for this example, ``getName()`` would have returned
|
||||
``"AirStartExample"`` if this method hadn't overridden it).
|
||||
* The ``getDescription()`` method in lines 24-26, which provides a brief description of the purpose of the extension.
|
||||
This is the method that provides the text for the :guilabel:`Info` button dialog shown in the first section of this page.
|
||||
* The listener itself in lines 28-34, which provides a single ``startSimulation()`` method. When the simulation starts
|
||||
executing, this listener is called, and the rocket is set to an altitude of 1000 meters.
|
||||
|
||||
This will create the extension when it's compiled, but it won't put it in the simulation extension menu. To be able to
|
||||
actually use it, we need a provider, like this:
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
package net.sf.openrocket.simulation.extension.example;
|
||||
|
||||
import net.sf.openrocket.plugin.Plugin;
|
||||
import net.sf.openrocket.simulation.extension.AbstractSimulationExtensionProvider;
|
||||
|
||||
@Plugin
|
||||
public class AirStartExampleProvider extends AbstractSimulationExtensionProvider {
|
||||
public AirStartExampleProvider() {
|
||||
super(AirStartExample.class, "Launch conditions", "Air-start example");
|
||||
}
|
||||
}
|
||||
|
||||
This class adds your extension to the extension menu. The first ``String`` (``"Launch Conditions"``) is the first menu level,
|
||||
while the second (``"Air-start example"``) is the actual menu entry. These strings can be anything you want; using a
|
||||
first level entry that didn't previously exist will add it to the first level menu.
|
||||
|
||||
Try it! Putting the extension in a file named :file:`core/src/net/sf/openrocket/simulation/extensions/example/AirStartExample.java`
|
||||
and the provider in :file:`core/src/net/sf/openrocket/simulation/extensions/example/AirStartExampleProvider.java`, compiling,
|
||||
and running will give you a new entry in the extensions menu; adding it to the simulation will cause your simulation to
|
||||
start at an altitude of 1000 meters.
|
||||
|
||||
Adding a Configurator
|
||||
---------------------
|
||||
|
||||
To be able to configure the extension at runtime, we need to write a configurator and provide it with a way to
|
||||
communicate with the extension. First, we'll modify the extension as follows:
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
package net.sf.openrocket.simulation.extension.example;
|
||||
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.extension.AbstractSimulationExtension;
|
||||
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
/**
|
||||
* Simulation extension that launches a rocket from a specific altitude.
|
||||
*/
|
||||
public class AirStartExample extends AbstractSimulationExtension {
|
||||
|
||||
public void initialize(SimulationConditions conditions) throws SimulationException {
|
||||
conditions.getSimulationListenerList().add(new AirStartListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Air-Start Example";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Simple extension example for air-start";
|
||||
}
|
||||
|
||||
public double getLaunchAltitude() {
|
||||
return config.getDouble("launchAltitude", 1000.0);
|
||||
}
|
||||
|
||||
public void setLaunchAltitude(double launchAltitude) {
|
||||
config.put("launchAltitude", launchAltitude);
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
private class AirStartListener extends AbstractSimulationListener {
|
||||
|
||||
@Override
|
||||
public void startSimulation(SimulationStatus status) throws SimulationException {
|
||||
status.setRocketPosition(new Coordinate(0, 0, getLaunchAltitude()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
This adds two methods to the extension (``getLaunchAltitude()`` and ``setLaunchAltitude()``), and calls ``getLaunchAltitude()``
|
||||
from within the listener to obtain the configured launch altitude. ``config`` is a ``Config`` object, provided by
|
||||
``AbstractSimulationExtension`` (so it isn't necessary to call a constructor yourself).
|
||||
:file:`core/src/net/sf/openrocket/util/Config.java` includes methods to interact with a configurator, allowing the
|
||||
extension to obtain ``double``, ``string``, and other configuration values.
|
||||
|
||||
In this case, we'll only be defining a single configuration field in our configurator, ``"launchAltitude"``.
|
||||
|
||||
The ``getLaunchAltitude()`` method obtains the air-start altitude for the simulation from the configuration, and sets a
|
||||
default air-start altitude of 1000 meters. Our ``startSimulation()`` method has been modified to make use of this to obtain
|
||||
the user's requested air-start altitude from the configurator, in place of the original hard-coded value.
|
||||
|
||||
The ``setLaunchAltitude()`` method places a new launch altitude in the configuration. While our extension doesn't make
|
||||
use of this method directly, it will be necessary for our configurator. The call to ``fireChangeEvent()`` in this method
|
||||
assures that the changes we make to the air-start altitude are propagated throughout the simulation.
|
||||
|
||||
The configurator itself looks like this:
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
package net.sf.openrocket.simulation.extension.example;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.plugin.Plugin;
|
||||
import net.sf.openrocket.simulation.extension.AbstractSwingSimulationExtensionConfigurator;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
@Plugin
|
||||
public class AirStartConfigurator extends AbstractSwingSimulationExtensionConfigurator<AirStart> {
|
||||
|
||||
public AirStartConfigurator() {
|
||||
super(AirStart.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getConfigurationComponent(AirStart extension, Simulation simulation, JPanel panel) {
|
||||
panel.add(new JLabel("Launch altitude:"));
|
||||
|
||||
DoubleModel m = new DoubleModel(extension, "LaunchAltitude", UnitGroup.UNITS_DISTANCE, 0);
|
||||
|
||||
JSpinner spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
panel.add(spin, "w 65lp!");
|
||||
|
||||
UnitSelector unit = new UnitSelector(m);
|
||||
panel.add(unit, "w 25");
|
||||
|
||||
BasicSlider slider = new BasicSlider(m.getSliderModel(0, 5000));
|
||||
panel.add(slider, "w 75lp, wrap");
|
||||
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
|
||||
After some boilerplate, this class creates a new ``DoubleModel`` to manage the air-start altitude. The most important things
|
||||
to notice about the ``DoubleModel`` constructor are the parameters ``"LaunchAltitude"`` and ``UnitGroup.UNITS_DISTANCE``.
|
||||
|
||||
* ``"LaunchAltitude"`` is used by the system to synthesize calls to the ``getLaunchAltitude()`` and ``setLaunchAltitude()``
|
||||
methods mentioned earlier. The name of the ``DoubleModel``, ``"LaunchAltitude"``, **MUST** match the names of the corresponding
|
||||
``set`` and ``get`` methods exactly. If they don't, there will be an exception at runtime when the user attempts to change the value.
|
||||
* ``UnitGroup.UNITS_DISTANCE`` specifies the unit group to be used by this ``DoubleModel``. OpenRocket uses SI (MKS) units internally,
|
||||
but allows users to select the units they wish to use for their interface. Specifying a ``UnitGroup`` provides the conversions
|
||||
and unit displays for the interface. The available ``UnitGroup`` options are defined in :file:`core/src/net/sf/openrocket/unit/UnitGroup.java`.
|
||||
|
||||
The remaining code in this method creates a ``JSpinner``, a ``UnitSelector``, and a ``BasicSlider`` all referring to this ``DoubleModel``.
|
||||
When the resulting configurator is displayed, it looks like this:
|
||||
|
||||
.. figure:: /img/user_guide/simulation_extensions/Example_Configurator.png
|
||||
:align: center
|
||||
:width: 45%
|
||||
:figclass: or-image-border
|
||||
:alt: Example configurator
|
||||
|
||||
Example configurator.
|
||||
|
||||
The surrounding Dialog window and the **Close** button are provided by the system.
|
||||
|
||||
Example User Extensions Provided With OpenRocket
|
||||
================================================
|
||||
|
||||
Several examples of user extensions are provided in the OpenRocket source tree. As mentioned previously, the extensions
|
||||
are all located in :file:`core/src/net/sf/openrocket/simulation/extension/example` and their configurators are all located
|
||||
in :file:`swing/src/net/sf/openrocket/simulation/extension/example`. Also recall that every extension has a corresponding
|
||||
provider.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Purpose
|
||||
- Extension
|
||||
- Configurator
|
||||
* - Set air-start altitude and velocity
|
||||
- `AirStart.java`
|
||||
- `AirStartConfigurator.java`
|
||||
* - Save some simulation values as a CSV file
|
||||
- `CSVSave.java`
|
||||
- *(none)*
|
||||
* - Calculate damping moment coefficient after every simulation step
|
||||
- `DampingMoment.java`
|
||||
- *(none)*
|
||||
* - Print summary of simulation progress after each step
|
||||
- `PrintSimulation.java`
|
||||
- *(none)*
|
||||
* - Active roll control
|
||||
- `RollControl.java`
|
||||
- `RollControlConfigurator.java`
|
||||
* - Stop simulation at specified time or number of steps
|
||||
- `StopSimulation`
|
||||
- `StopSimulationConfigurator`
|
||||
|
||||
.. note::
|
||||
Documentation for adding user-created simulation listeners, without making use of the full extension mechanism, is also
|
||||
available at ``Simulation Listeners``.
|