Difference between revisions of "Importing and Exporting to Other Applications"

From OpenRocket wiki
Jump to navigation Jump to search
(Created page with "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 e...")
 
 
(62 intermediate revisions by the same user not shown)
Line 1: Line 1:
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.
+
<div style="text-align: center;">
 +
<div style="float: left;">[[Simulation Extensions|&larr; Simulation Extensions]]</div>
 +
<div style="float: right;">[[FAQ|Frequently Asked Questions &rarr;]]</div>
 +
[[Main Page|&uarr; Back to Contents]]
 +
</div>
  
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!'''
+
{{UserGuideHelp}}
  
== Adding an Existing Extension to a Simulation ==
 
  
Extensions are added to a simulation through a menu in the "Simulation Options" tab.
+
__TOC__
# Open a .ork file and go to the '''Flight Simulations''' tab
 
# Click the '''Edit simulation''' button to open the '''Edit simulation''' dialog.
 
# Go to the '''Simulation options''' tab.
 
# Click the '''Add extension''' button
 
This will open a menu similar to the one in the following screenshot:
 
  
[[File:Extension-menu.png]]
+
= Overview =
  
Clicking on the name of an extension will add it to the simulation; if it has a configuration dialog the dialog will be opened:
+
INSERT TEXT. . .
  
[[File:Air-start-configuration.png]]
+
= RASAero II =
  
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:
+
RASAero II (often simply caller RASAero) is available from [http://rasaero.com/ <span style="color:blue"><b>Rogers Aeroscience</b>], copyrighted as RASAero Aerodynamic Analysis and Flight Simulation Software by Charles E. Rogers and David Cooper.
  
[[File:Air-start-pane.png]]
+
RASAero is a combined aerodynamic analysis and flight simulation software package for model rockets and high power rockets, amateur rockets, and sounding rockets that is <b>single and multi-stage capable</b>.  RASAero supports <b>nested upper stages</b> (an upper stage motor which slides into the booster using a "boattail" component) and features <b>protuberance drag models</b> for missile raceways, camera shrouds, fin brackets, and so on. RASAero can also be used for <b>predicting aerodynamic coefficients</b> for use in other flight simulation programs for orbital rockets.
  
== Creating a New OpenRocket Extension ==
+
The RASAero aerodynamic prediction methods are purported to be the most accurate available for model, high power, and amateur rockets, and are said to be of equivalent accuracy to professional engineering method aerodynamic analysis codes used for missiles, sounding rockets, and space launch vehicles.<br>
  
The remainder of this page will describe how a new simulation extension is created.
+
== Basic Structure ==
  
===Preliminary Concepts===
+
The RASAero basic structure requires a very specific architecture which must be followed if a design is to be imported from or exported to RASAero. Because OpenRocket is capable of importing more complex structures than what it can export, the rules governing the OpenRocket RASAero import and export features will be discussed with more particularity in those subsections.
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====
+
With that in mind, a design file created with RASAero only has the external dimensions of the airframe without any internal components (except up to two parachutes). RASAero does not know or use internal or individual external component characteristics, such as wall thickness, material used, or density or weight. At the time the motor is selected, the user is expected to measure and provide the loaded center of gravity and loaded weight of the vehicle at that stage.
As a simulation proceeds, it maintains its state in a <code>SimulationStatus</code>. The <code>SimulationStatus</code> 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 <code>SimulationStatus</code> object.
 
  
You can obtain current information regarding the state of the simulation by calling <code>get*()</code> methods. For instance, the rocket's current position is returned by calling <code>getRocketPosition()</code>; the rocket's position can be changed by calling <code>setRocketPosition<Coordinate position></code>.  All of the <code>get*()</code> and <code>set*()</code> methods can be found in <code>code/src/net/sf/openrocket/simulation/SimulationStatus.java</code>. Note that while some information can be obtained in this way, it is not as complete as that found in <code>FlightData</code> and <code>FlightDataBranch</code> objects.
+
As for recovery devices, RASAero allows up to two parachutes; no streamers or other decent devices. To have any recovery event at all, <em>Recovery Event 1</em> <b>MUST</b> occur at <em>Apogee</em> and <b>MUST</b> be a <em>parachute</em>. If either condition is not met, no recovery event will occur, not the first recovery event and not the second recovery event. If there is a second recovery event, <em>Recovery Event 2</em> <b>MUST</b> occur at <em>Altitude</em>, a stated altitude in feet above ground level, and <b>MUST</b> be a <em>parachute</em>. If these conditions are not met, <em>Recovery Event 2</em> will <b>NOT</b> occur.
  
====Flight Data====
+
Although RASAero affords the user a host of other settings to more accurately predict flight characteristics and results, those settings have defaults that do not require changes before running a simulation, and RASAero and OpenRocket will pass those values to the other during the import and export process.
OpenRocket refers to simulation variables as <code>FlightDataType</code>s, which are <code>List&lt;Double&gt;</code> objects with one list for each simulation variable and one element in the list for each time step.  To obtain a <code>FlightDataType</code>, for example the current motor mass, from <code>flightData</code>, we call <code>flightData.get(FlightDataType.TYPE_MOTOR_MASS))</code>. The standard <code>FlightDataType</code> lists are all created in <code>core/src/net/sf/openrocket/simulation/FlightDataType.java</code>; the mechanism for creating a new <code>FlightDataType</code> if needed for your extension will be described later.
 
  
Data from the current simulation step can be obtained with e.g. <code>flightData.getLast(FlightDataType.TYPE_MOTOR_MASS)</code>.
+
== Import Design Architecture Differences ==
  
The simulation data for each stage of the rocket's flight is referred to as a <code>FlightDataBranch</code>.  Every simulation has at least one <code>FlightDataBranch</code> for its sustainer, and will have additional branches for its boosters.
+
RASAero and OpenRocket have several material differences in component compatibilities that affect importation. The significant among these are the RASAero boattail component, rail guide types, and protuberances.
  
Finally, the collection of all of the <code>FlightDataBranch</code>es and some summary data for the simulation is stored in a <code>FlightData</code> object.
+
<u>Boattails</u>: In RASAero, a boattail is an upper stage reverse transition which slides into the next stage booster. A boattail may be used as the last component of Stage 1 (a transition may also be used as the last component). The last component of the boosters in RASAero may only be a body tube or a boattail (transitions may not be used as the last booster component). During the importation process, OpenRocket converts RASAero boattails into inline pod transitions,
  
====Flight Conditions====
+
<u>Rail Guide</u>: In RASAero, the user may choose from several types of rail guides, however, OpenRocket only supports launch lugs and rail buttons. Any other type of rail guide will be stripped from the design during the importation process.
Current data regarding the aerodynamics of the flight itself are stored in a <code>FlightConditions</code> 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 <code>AtmosphericConditions</code>
 
  
====Simulation Listeners====
+
<u>Protuberances</u>: RASAero allows the user to create protuberances for which it has drag models. This allows RASAero to simulate missile raceways, camera shrouds, fin brackets, and other protuberances. <em>This feature is not supported in OpenRocket</em> and all protuberances will be stripped from the design during the importation process.<br>
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 <code>SimulationListener</code>, <code>SimulationComputationListener</code>, and <code>SimulationEventListener</code>.
 
  
All of these interfaces are implemented by the abstract class <code>AbstractSimulationListener</code>. 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
+
=== Accessing the Import Feature ===
  
<pre>
+
The RASAero import feature in OpenRocket is accessed from the <em>File</em> menu. First, left-click on <em>File</em> to open the drop-down menu, then left-click on <em>Import</em> to open the application menu, and select RASAero with a third left-cleick.
public void startSimulation(SimulationStatus status) throws SimulationException {
 
    status.setRocketPosition(new Coordinate(0, 0, getLaunchAltitude()));
 
    status.setRocketVelocity(status.getRocketOrientationQuaternion().rotate(new Coordinate(0, 0, getLaunchVelocity())));
 
}
 
</pre>
 
  
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.
+
[[File:2022.02.01.02.Pull Down Menu.png|thumb|600 px|center|The <em>Pull-Down Menu</em>.]] <br/>
  
The full set of listener methods, with documentation regarding when they are called, can be found in <code>core/src/net/sf/openrocket/AbstractSimulationListener.java</code>.
+
When that third left-click is made, the import file menu will open. If you are new to the RASAero import feature, you may want to navigate to the example directory that is packaged with RASAero and select one of the example designs. For this discussion, the "<em>CalIsp1.CDX1</em> file was selected, then "<em>Open</em> was left-clicked.
  
The listener methods can have three return value types:
+
[[File:2022.02.02.01.Import Directory.png|thumb|600 px|center|The <em>Import Directory</em>.]]
 +
 +
[[File:2022.02.03.01.Imported Design.png|thumb|600 px|center|The <em>Imported Design</em>.]]
  
* The <code>startSimulation()</code>, <code>endSimulation()</code>, and <code>postStep()</code> are called at a specific point of the simulation. They are void methods and do not return any value.
+
Five easy steps. It's as simple as that.
  
* The <code>preStep()</code> and event-related hook methods return a boolean value indicating whether the associated action should be taken or not.  A return value of <code>true</code> indicates that the action should be taken as normally would be (default), <code>false</code> will inhibit the action.
+
=== Recovery Device Import Position Assumptions ===
  
* 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 <code>null</code> or <code>Double.NaN</code> to use the original values (default), or return an overriding value.
+
Where RASAero allows the use of two recovery devices, but does not specify where the recovery devices are positioned within the airframe (a requirement in OpenRocket), the importation process attempts to use the following common position rules:
  
Every listener receives a <code>SimulationStatus</code> (see above) object as the first argument, and may also have additional arguments.
+
<u>One Recovery Device</u>
 
 
Each listener method may also throw a <code>SimulationException</code>.  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 <code>RuntimeException</code> 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 <code>FlightEvent.SIMULATION_END</code> to the simulation event queue:
+
<ul>
<pre>
+
<li><strong>One or more body tubes</strong>: Recovery Device 1 (Apogee) is positioned below the top of Body Tube 1.</li>
status.getEventQueue().add(new FlightEvent(FlightEvent.Type.SIMULATION_END, status.getSimulationTime(), null));
+
</ul>
</pre>
 
This will cause the simulation to be terminated normally.
 
  
=== Creating a New Simulation Extension ===
+
<u>Two Recovery Devices</u>
  
Creating an extension for OpenRocket requires writing three classes:
+
<ul>
 +
<li><strong>One body tube</strong>: Recovery Device 1 (Apogee) is positioned below the top of Body Tube 1; Recovery Device 2 (Altitude) is positioned below the top of Body Tube 1</li>
 +
<li><strong>Two body tubes</strong>: Recovery Device 2 (Altitude) is positioned below the top of Body Tube 1; Recovery Device 1 (Apogee) is positioned below the top of Body Tube 2</li>
 +
<li><strong>Three body tubes</strong>: Recovery Device 2 (Altitude) is positioned below the top of Body Tube 1; Recovery Device 1 (Apogee) is positioned below the top of Body Tube 2</li>
 +
<li><strong>Four or more body tubes</strong>: Recovery Device 2 (Altitude) is positioned below the top of Body Tube 2; Recovery Device 1 (Apogee) is positioned below the top of Body Tube 3</li>
 +
</ul>
  
* A listener, which extends <code>AbstractSimulationListener</code>. This will be the bulk of your extension, and performs all the real work.
+
== Export Design Architecture Differences ==
  
* An extension, which extends <code>AbstractSimulationExtension</code>. This inserts your listener into the simulation. Your listener can (and ordinarily will) be private to your extension.
+
Where OpenRocket is intended to assist the user to design and construct the rocket, as well as simulate its flights, OpenRocket designs have internal components anf other characteristics that are incompatible with RASAero. Because these incompatibilities are removed, where possible, when the design is exported, all of the internal components and many of the airframe characteristics will be lost in the design is exported to RASAero, thes modified and saved, before being imported back into OpenRocket. The following is a list of a few elements to consider when creating a design that will be exported to RASAero.
  
* A provider, which extends <code>AbstractSimulationExtensionProvider</code> This puts your extension into the menu described above.
+
<ul>
 +
<li><strong>Airframe parameters</strong>: RASAero requires that the first component be a nose cone and that the second component be a body tube or boattail. After the second component, any combination of body tubes, transitions, fin cans, and boattails may be utilized, with the following limitations.</li>
 +
<li><strong>Fin parameters</strong>: Fins must be trapezoidal in shape and can only be positioned on a body tube.</li>
 +
<li><strong>Rail guides</strong>: RASAero creates launch lugs and rail buttons as sets, so in OpenRocket the instance count of these component should be set to 2; do not create two separate launch lugs or rail buttons. Although RASAero support launch shoes, OpenRocket does not.</li>
 +
<li><strong>Boosters</strong>: </li>
 +
<li><strong>Pods</strong>: </li>
 +
</ul>
  
In addition, if your extension will have a configuration GUI, you will need to write:
+
INSERT TEXT. . .
  
* A configurator, which extends <code>AbstractSwingSimulationExtensionConfigurator&lt;E&gt;</code>
+
=== Accessing the Export Feature ===
  
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
+
INSERT TEXT. . .
  
<code>core/src/net/sf/openrocket/simulation/extension/example/</code>
+
=== Export Assumptions ===
  
This is where the extension examples provided with OpenRocket are located. Your configurator, if any, will logically go in
+
INSERT TEXT. . .
  
<code>swing/src/net/sf/openrocket/simulation/extension/example/</code>
+
= Rocksim 10 =
  
====Extension Example====
+
INSERT TEXT. . . <br><br>
  
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 run time. This is a simplified version of the <code>AirStart</code> extension located in the OpenRocket source code tree; that class also sets a start velocity.
+
== Basic Structure ==
  
{| align="top"
+
INSERT TEXT. . .
| <pre>
 
1
 
2
 
3
 
4
 
5
 
6
 
7
 
8
 
9
 
10
 
11
 
12
 
13
 
14
 
15
 
16
 
17
 
18
 
19
 
20
 
21
 
22
 
23
 
24
 
25
 
26
 
27
 
28
 
29
 
30
 
31
 
32
 
33
 
34
 
35
 
</pre>
 
| <pre>
 
package net.sf.openrocket.simulation.extension.example;
 
  
import net.sf.openrocket.simulation.SimulationStatus;
+
== Import Design Architectural Differences ==
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;
 
  
/**
+
INSERT TEXT. . .  
* Simulation extension that launches a rocket from a specific altitude.
 
*/
 
public class AirStartExample extends AbstractSimulationExtension {
 
  
    public void initialize(SimulationConditions conditions) throws SimulationException {
+
=== Accessing the Import Feature ===
        conditions.getSimulationListenerList().add(new AirStartListener());
 
    }
 
  
    @Override
+
INSERT TEXT. . .
    public String getName() {
 
        return "Air-Start Example";
 
    }
 
  
    @Override
+
=== Import Assumptions ===
    public String getDescription() {
 
        return "Simple extension example for air-start";
 
    }
 
  
    private class AirStartListener extends AbstractSimulationListener {
+
INSERT TEXT. . . <br><br>
  
        @Override
+
== Export Design Architecture Differences ==
        public void startSimulation(SimulationStatus status) throws SimulationException {
 
            status.setRocketPosition(new Coordinate(0, 0, 1000.0));
 
        }
 
    }
 
}
 
</pre>
 
|}
 
  
There are several important features in this example:
+
INSERT TEXT. . .
* The <code>initialize()</code> method in lines 14-16, which adds the listener to the simulations <code>List</code> of listeners. This is the only method that is required to be defined in your extension.
 
* The <code>getName()</code> method in lines 19-21, which provides the extension's name.  A default <code>getName()</code> is provided by <code>AbstractSimulationExtension</code>, which simply uses the classname (so for this example, <code>getName()</code> would have returned <code>"AirStartExample"</code> if this method hadn't overridden it).
 
* The <code>getDescription()</code> 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 <code>Info</code> button dialog shown in the first section of this page.
 
* The listener itself in lines 28-34, which provides a single <code>startSimulation()</code> method.  When the simulation for 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:
+
=== Accessing the Export Feature ===
  
{| align="top"
+
INSERT TEXT. . .
| <pre>
 
1
 
2
 
3
 
4
 
5
 
6
 
7
 
8
 
9
 
10
 
11
 
</pre>
 
| <pre>
 
package net.sf.openrocket.simulation.extension.example;
 
  
import net.sf.openrocket.plugin.Plugin;
+
=== Export Assumptions ===
import net.sf.openrocket.simulation.extension.AbstractSimulationExtensionProvider;
 
  
@Plugin
+
INSERT TEXT. . .
public class AirStartExampleProvider extends AbstractSimulationExtensionProvider {
 
    public AirStartExampleProvider() {
 
        super(AirStartExample.class, "Launch conditions", "Air-start example");
 
    }
 
}
 
</pre>
 
|}
 
  
This class adds your extension to the extension menu.  The first <code>String</code> (<code>"Launch Conditions"</code>) is the first menu level, while the second (<code>"Air-start example"</code>) 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.
+
----
 
+
<div style="text-align: center;">
Try it! Putting the extension in a file named <code>core/src/net/sf/openrocket/simulation/extensions/example/AirStartExample.java</code> and the provider in <code>core/src/net/sf/openrocket/simulation/extensions/example/AirStartExampleProvider.java</code>, 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.
+
<div style="float: left;">[[Getting Started|&larr; Getting Started]]</div>
 
+
<div style="float: right;">[[Basic Flight Simulation|Basic Flight Simulation &rarr;]]</div>
====Adding a Configurator====
+
[[Main Page|&uarr; Back to Contents]]
To be able to configure the extension at run time, 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:
+
</div>
 
 
{| align="top"
 
| <pre>
 
1
 
2
 
3
 
4
 
5
 
6
 
7
 
8
 
9
 
10
 
11
 
12
 
13
 
14
 
15
 
16
 
17
 
18
 
19
 
20
 
21
 
22
 
23
 
24
 
25
 
26
 
27
 
28
 
29
 
30
 
31
 
32
 
33
 
34
 
35
 
36
 
37
 
38
 
39
 
40
 
41
 
42
 
43
 
44
 
45
 
</pre>
 
| <pre>
 
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()));
 
        }
 
    }
 
}
 
</pre>
 
|}
 
 
 
This adds two methods to the extension (<code>getLaunchAltitude()</code> and <code>setLaunchAltitude()</code>), and calls <code>getLaunchAltitude()</code> from within the listener to obtain the configured launch altitude. <code>config</code> is a <code>Config</code> object, provided by <code>AbstractSimulationExtension</code> (so it isn't necessary to call a constructor yourself). <code>core/src/net/sf/openrocket/util/Config.java</code> includes methods to interact with a configurator, allowing the extension to obtain <code>double</code>, <code>string</code>, and other configuration values.
 
 
 
In this case, we'll only be defining a single configuration field in our configurator, <code>"launchAltitude"</code>.
 
 
 
The <code>getLaunchAltitude()</code> method obtains the air-start altitude for the simulation from the configuration, and sets a default air-start altitude of 1000 meters. Our <code>startSimulation()</code> 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 <code>setLaunchAltitude()</code> 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 <code>fireChangeEvent()</code> 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
 
{| align="top"
 
| <pre>
 
1
 
2
 
3
 
4
 
5
 
6
 
7
 
8
 
9
 
10
 
11
 
12
 
13
 
14
 
15
 
16
 
17
 
18
 
19
 
20
 
21
 
22
 
23
 
24
 
25
 
26
 
27
 
28
 
29
 
30
 
31
 
32
 
33
 
34
 
35
 
36
 
37
 
38
 
39
 
30
 
31
 
42
 
43
 
</pre>
 
| <pre>
 
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;
 
    }
 
}
 
</pre>
 
|}
 
 
 
After some boilerplate, this class creates a new <code>DoubleModel</code> to manage the airstart altitude.  The most important things to notice about the <code>DoubleModel</code> constructor are the parameters <code>"LaunchAltitude"</code> and <code>UnitGroup.UNITS_DISTANCE</code>.
 
* <code>"LaunchAltitude"</code>  is used by the system to synthesize calls to the <code>getLaunchAltitude()</code> and <code>setLaunchAltitude()</code> methods mentioned earlier. The name of the <code>DoubleModel</code>, <code>"LaunchAltitude"</code>, '''''MUST''''' match the names of the corresponding <code>set</code> and <code>get</code> methods exactly.  If they don't, there will be an exception at run time when the user attempts to change the value.
 
* <code>UnitGroup.UNITS_DISTANCE</code> specifies the unit group to be used by this <code>DoubleModel</code>. OpenRocket uses SI (MKS) units internally, but allows users to select the units they wish to use for their interface.  Specifying a <code>UnitGroup</code> provides the conversions and unit displays for the interface.  The available <code>UnitGroup</code>s are defined in <code>core/src/net/sf/openrocket/unit/UnitGroup.java</code>
 
 
 
The remaining code in this method creates a <code>JSpinner</code>, a <code>UnitSelector</code>, and a <code>BasicSlider</code> all referring to this <code>DoubleModel</code>.  When the resulting configurator is displayed, it looks like this:
 
 
 
[[File:Example_Configurator.png]]
 
 
 
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 <code>core/src/net/sf/openrocket/simulation/extension/example</code> and their configurators are all located in <code>swing/src/net/sf/openrocket/simulation/extension/example</code>.  Also recall that every extension has a corresponding provider.
 
 
 
{| class="wikitable" style="margin:auto"
 
!Purpose!!Extension!!Configurator
 
|-
 
| Set air-start altitude and velocity||<code>AirStart.java</code>||<code>AirStartConfigurator.java</code>
 
|-
 
| Save some simulation values as a CSV file||<code>CSVSave.java</code>||''(none)''
 
|-
 
| Calculate damping moment coefficient after every simulation step||<code>DampingMoment.java</code>||''(none)''
 
|-
 
| Print summary of simulation progress after each step||<code>PrintSimulation.java</code>||''(none)''
 
|-
 
| Active roll control||<code>RollControl.java</code>||<code>RollControlConfigurator.java</code>
 
|-
 
| Stop simulation at specified time or number of steps||<code>StopSimulation</code>||<code>StopSimulationConfigurator</code>
 
|}
 
''Note:  documentation for adding user-created simulation listeners, without making use of the full extension mechanism, is also available at [[Simulation Listeners]]''
 

Latest revision as of 02:59, 13 April 2023

↑ Back to Contents

The current User's Guide is very much a work in progress, any help would be greatly appreciated!
If you'd like to contribute something, just hit the 'Edit' tab at the top.


Overview[edit]

INSERT TEXT. . .

RASAero II[edit]

RASAero II (often simply caller RASAero) is available from Rogers Aeroscience, copyrighted as RASAero Aerodynamic Analysis and Flight Simulation Software by Charles E. Rogers and David Cooper.

RASAero is a combined aerodynamic analysis and flight simulation software package for model rockets and high power rockets, amateur rockets, and sounding rockets that is single and multi-stage capable. RASAero supports nested upper stages (an upper stage motor which slides into the booster using a "boattail" component) and features protuberance drag models for missile raceways, camera shrouds, fin brackets, and so on. RASAero can also be used for predicting aerodynamic coefficients for use in other flight simulation programs for orbital rockets.

The RASAero aerodynamic prediction methods are purported to be the most accurate available for model, high power, and amateur rockets, and are said to be of equivalent accuracy to professional engineering method aerodynamic analysis codes used for missiles, sounding rockets, and space launch vehicles.

Basic Structure[edit]

The RASAero basic structure requires a very specific architecture which must be followed if a design is to be imported from or exported to RASAero. Because OpenRocket is capable of importing more complex structures than what it can export, the rules governing the OpenRocket RASAero import and export features will be discussed with more particularity in those subsections.

With that in mind, a design file created with RASAero only has the external dimensions of the airframe without any internal components (except up to two parachutes). RASAero does not know or use internal or individual external component characteristics, such as wall thickness, material used, or density or weight. At the time the motor is selected, the user is expected to measure and provide the loaded center of gravity and loaded weight of the vehicle at that stage.

As for recovery devices, RASAero allows up to two parachutes; no streamers or other decent devices. To have any recovery event at all, Recovery Event 1 MUST occur at Apogee and MUST be a parachute. If either condition is not met, no recovery event will occur, not the first recovery event and not the second recovery event. If there is a second recovery event, Recovery Event 2 MUST occur at Altitude, a stated altitude in feet above ground level, and MUST be a parachute. If these conditions are not met, Recovery Event 2 will NOT occur.

Although RASAero affords the user a host of other settings to more accurately predict flight characteristics and results, those settings have defaults that do not require changes before running a simulation, and RASAero and OpenRocket will pass those values to the other during the import and export process.

Import Design Architecture Differences[edit]

RASAero and OpenRocket have several material differences in component compatibilities that affect importation. The significant among these are the RASAero boattail component, rail guide types, and protuberances.

Boattails: In RASAero, a boattail is an upper stage reverse transition which slides into the next stage booster. A boattail may be used as the last component of Stage 1 (a transition may also be used as the last component). The last component of the boosters in RASAero may only be a body tube or a boattail (transitions may not be used as the last booster component). During the importation process, OpenRocket converts RASAero boattails into inline pod transitions,

Rail Guide: In RASAero, the user may choose from several types of rail guides, however, OpenRocket only supports launch lugs and rail buttons. Any other type of rail guide will be stripped from the design during the importation process.

Protuberances: RASAero allows the user to create protuberances for which it has drag models. This allows RASAero to simulate missile raceways, camera shrouds, fin brackets, and other protuberances. This feature is not supported in OpenRocket and all protuberances will be stripped from the design during the importation process.

Accessing the Import Feature[edit]

The RASAero import feature in OpenRocket is accessed from the File menu. First, left-click on File to open the drop-down menu, then left-click on Import to open the application menu, and select RASAero with a third left-cleick.

The Pull-Down Menu.


When that third left-click is made, the import file menu will open. If you are new to the RASAero import feature, you may want to navigate to the example directory that is packaged with RASAero and select one of the example designs. For this discussion, the "CalIsp1.CDX1 file was selected, then "Open was left-clicked.

The Import Directory.
The Imported Design.

Five easy steps. It's as simple as that.

Recovery Device Import Position Assumptions[edit]

Where RASAero allows the use of two recovery devices, but does not specify where the recovery devices are positioned within the airframe (a requirement in OpenRocket), the importation process attempts to use the following common position rules:

One Recovery Device

  • One or more body tubes: Recovery Device 1 (Apogee) is positioned below the top of Body Tube 1.

Two Recovery Devices

  • One body tube: Recovery Device 1 (Apogee) is positioned below the top of Body Tube 1; Recovery Device 2 (Altitude) is positioned below the top of Body Tube 1
  • Two body tubes: Recovery Device 2 (Altitude) is positioned below the top of Body Tube 1; Recovery Device 1 (Apogee) is positioned below the top of Body Tube 2
  • Three body tubes: Recovery Device 2 (Altitude) is positioned below the top of Body Tube 1; Recovery Device 1 (Apogee) is positioned below the top of Body Tube 2
  • Four or more body tubes: Recovery Device 2 (Altitude) is positioned below the top of Body Tube 2; Recovery Device 1 (Apogee) is positioned below the top of Body Tube 3

Export Design Architecture Differences[edit]

Where OpenRocket is intended to assist the user to design and construct the rocket, as well as simulate its flights, OpenRocket designs have internal components anf other characteristics that are incompatible with RASAero. Because these incompatibilities are removed, where possible, when the design is exported, all of the internal components and many of the airframe characteristics will be lost in the design is exported to RASAero, thes modified and saved, before being imported back into OpenRocket. The following is a list of a few elements to consider when creating a design that will be exported to RASAero.

  • Airframe parameters: RASAero requires that the first component be a nose cone and that the second component be a body tube or boattail. After the second component, any combination of body tubes, transitions, fin cans, and boattails may be utilized, with the following limitations.
  • Fin parameters: Fins must be trapezoidal in shape and can only be positioned on a body tube.
  • Rail guides: RASAero creates launch lugs and rail buttons as sets, so in OpenRocket the instance count of these component should be set to 2; do not create two separate launch lugs or rail buttons. Although RASAero support launch shoes, OpenRocket does not.
  • Boosters:
  • Pods:

INSERT TEXT. . .

Accessing the Export Feature[edit]

INSERT TEXT. . .

Export Assumptions[edit]

INSERT TEXT. . .

Rocksim 10[edit]

INSERT TEXT. . .

Basic Structure[edit]

INSERT TEXT. . .

Import Design Architectural Differences[edit]

INSERT TEXT. . .

Accessing the Import Feature[edit]

INSERT TEXT. . .

Import Assumptions[edit]

INSERT TEXT. . .

Export Design Architecture Differences[edit]

INSERT TEXT. . .

Accessing the Export Feature[edit]

INSERT TEXT. . .

Export Assumptions[edit]

INSERT TEXT. . .


↑ Back to Contents