Add some more pages

This commit is contained in:
SiboVG 2024-05-29 13:26:32 +02:00
parent f49ce08ae1
commit 816df855e2
41 changed files with 1781 additions and 19 deletions

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -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

View File

@ -2,6 +2,13 @@
Codebase Walkthrough
********************
.. contents:: Table of Contents
:depth: 2
:local:
:backlinks: none
----
Important Modules and Packages
==============================

View File

@ -10,6 +10,8 @@ for our documentation, how to edit and build the documentation, and the style gu
:local:
:backlinks: none
----
Why Sphinx?
===========

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -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::

View File

@ -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):
==========================================

View File

@ -13,6 +13,8 @@ the next section.
:local:
:backlinks: none
----
.. _the_user_interface:
The User interface

View File

@ -7,6 +7,8 @@ Installation Instructions
:local:
:backlinks: none
----
Introduction
============

View 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.

View File

@ -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, theres 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>>

View File

@ -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

View File

@ -19,6 +19,8 @@ Then we'll build a rocket from scratch to see how its done.
:local:
:backlinks: none
----
Component Configuration Window
==============================

View 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>`_.

View 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 rockets 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 rockets 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 rockets 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 rockets 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 rockets rotational inertia (moment of inertia), how the
rockets mass is distribution about the axis (center of gravity), with larger moments requiring more torque to change
the rockets rate of rotation. When subcomponent mass and center of gravity values are overridden, the rockets 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 rockets 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 rockets 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
rockets calculated rotational inertia. The user simply checks the assembly components 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 rockets rotational inertia than overriding all
the subcomponent values.
Adjustable Weight Systems
~~~~~~~~~~~~~~~~~~~~~~~~~
Using the assembly components 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 rockets **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.

View 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.*

View 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``.